[Hibernate-JIRA] Created: (HHH-3353) Id of an entity is not set when it is a proxy in a collection
by Pascal Perez (JIRA)
Id of an entity is not set when it is a proxy in a collection
-------------------------------------------------------------
Key: HHH-3353
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3353
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.1
Environment: Observed on MySQL 5, unit tested on HSQLDB.
Reporter: Pascal Perez
Attachments: entities.zip
In plain English:
With three entities, Item, Comment and Category such that
Item has multiple Comment (one to many)
Comment has one or no Category (many to one)
have one item with one comment that is linked to one category. Load the item, read the category's id. It's not being set by Hibernate.
In unit test (fails at the very last assertNotSame):
// creating an item
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Item item = new Item();
Comment comment = new Comment();
comment.item = item;
item.comments.add(comment);
comment.category = new Category();
session.save(item);
session.save(comment.category);
assertNotSame("after save, category's id must not be 0",
0, comment.category.id);
tx.commit();
session.close();
// load the item and read the rating's id
session = sessionFactory.openSession();
item = (Item) session.get(Item.class, item.id);
assertNotSame("after load, category's id must not be 0",
0, item.comments.iterator().next().category.id);
session.close();
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 5 months
[Hibernate-JIRA] Created: (HHH-3374) Subselect fetching fetches all elements in link table instead only needed
by Alexander V. Zinin (JIRA)
Subselect fetching fetches all elements in link table instead only needed
-------------------------------------------------------------------------
Key: HHH-3374
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3374
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.6
Reporter: Alexander V. Zinin
I've some entity with many-to-many collection inside. Example:
public class Message implements Serializable {
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "message_has_file_attachment", joinColumns = {@JoinColumn(name = "message_id")},
inverseJoinColumns = {@JoinColumn(name = "file_attachment_id")})
@Fetch(value = FetchMode.SUBSELECT)
public Set<MessageImageFileAttachment> getFileAttachments() {
return fileAttachments;
}
}
I want to fetch this collection for items I've fetched. I do:
DetachedCriteria criteria = DetachedCriteria.forClass(messageClass);
criteria.setFetchMode("fileAttachments", FetchMode.SELECT);
List list = getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
if (list.size() > 0) {
Message message = (Message) list.get(0);
Hibernate.initialize(message.getFileAttachments());
}
And hibernate generates subquery like this:
select
fileattach0_.message_id as message1_1_,
fileattach0_.file_attachment_id as file2_1_,
messageima1_.id as id12_0_,
messageima1_.creationDate as creation3_12_0_,
messageima1_.hostname as hostname12_0_,
messageima1_.name as name12_0_,
messageima1_.path as path12_0_,
messageima1_.submited as submited12_0_,
messageima1_.description as descript8_12_0_,
messageima1_.hasSmallImage as hasSmall9_12_0_,
messageima1_.height as height12_0_,
messageima1_.smallHeight as smallHe11_12_0_,
messageima1_.smallWidth as smallWidth12_0_,
messageima1_.tinyHeight as tinyHeight12_0_,
messageima1_.tinyWidth as tinyWidth12_0_,
messageima1_.width as width12_0_
from
message_has_file_attachment fileattach0_
left outer join
file_attachment messageima1_
on fileattach0_.file_attachment_id=messageima1_.id
where
fileattach0_.message_id in (
select
this_.id
from
message this_
inner join
a_user user2_
on this_.user_id=user2_.id
left outer join
file_attachment articlemes3_
on this_.image_id=articlemes3_.id
)
So it fetched ALL rows in table ! And what happens if there will be a millions rows ?
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#performance
Subselect fetching - a second SELECT is used to retrieve the associated collections for all entities retrieved in a previous query or fetch. Unless you explicitly disable lazy fetching by specifying lazy="false", this second select will only be executed when you actually access the association.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 5 months
[Hibernate-JIRA] Created: (HHH-3079) composite-id, sequence and merge call result in a NullPointerException
by Jean-Baptiste Lalanne (JIRA)
composite-id, sequence and merge call result in a NullPointerException
----------------------------------------------------------------------
Key: HHH-3079
URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3079
Project: Hibernate3
Issue Type: Bug
Affects Versions: 3.2.5
Environment: Oracle 10/XE
Windows XP
JDK 1.5.0
Reporter: Jean-Baptiste Lalanne
Attachments: oneup-hibernate-test.zip
I got problem during the migration process from HB 2 to 3.2.5.
We use Oracle as DB, problem happens when calling merge on a persistent entity A. This instance A has a relation (one-to-many) to another entity B, this instance is transient and has a generated id (from an oracle sequence), it has also a one-to-many relation to a third entity C. This last one has a composite id that includes a reverse one-to-many link to B.
Here comes mapping definition, see attached eclipse project sample that runs with an Oracle XE :
<!-- entity A -->
<class name="EventImpl" table="EV_EVENT">
<id column="EVT_ID" name="id" type="java.lang.Long">
<generator class="sequence">
<param name="sequence">SEQ_EV_ID</param>
</generator>
</id>
</class>
<!-- entity B -->
<class name="ScheduleImpl" table="EV_SCHEDULE">
<!-- primary key -->
<id column="SCH_ID" name="id" type="java.lang.Long">
<generator class="sequence">
<param name="sequence">SEQ_EV_ID</param>
</generator>
</id>
<property column="LAB_ID" name="labId" not-null="true" type="java.lang.Long"/>
<set name="scheduleDetails" cascade="all-delete-orphan" lazy="false" inverse="true">
<key column="SCH_ID"/>
<one-to-many class="ScheduleDetailImpl"/>
</set>
</class>
<!-- entity C -->
<class name="ScheduleDetailImpl" table="EV_SCHEDULE_DETAIL">
<!-- Cache directive -->
<cache usage="read-write" />
<!-- Composite primary key -->
<composite-id name="id" class="ScheduleDetailImplPK">
<key-many-to-one
class="com.cegedim.oneup.events.srv.domain.schedule.impl.ScheduleImpl"
name="schedule"
column="SCH_ID"
/>
<key-property
column="LINE_RNK"
name="lineRnk"
type="java.lang.Long"
/>
</composite-id>
</class>
When calling merge on A i got this stacktrace, sounds like a bad propagation of the generated B PK during cascading. If i call saveOrUpdate all works fine, the HB2 code was calling the saveOrUpdateCopy and it worked fine. Does anybody got the same issue ? :
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:120)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:279)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:189)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:100)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:194)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:407)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:152)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:126)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at com.cegedim.oneup.events.srv.domain.Test.testMergeScheduleDetails(Test.java:67)
at com.cegedim.oneup.events.srv.domain.Test.run(Test.java:83)
at com.cegedim.oneup.events.srv.domain.Test.main(Test.java:126)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 6 months
[Hibernate-JIRA] Commented: (HHH-1523) LazyInitializationError on enabling query cache...
by Martijn van Tilburg (JIRA)
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1523?page=c... ]
Martijn van Tilburg commented on HHH-1523:
------------------------------------------
We run into this issue as well in an EJB3 project. We use:
JBoss AS 4.2.0 as application server
Hibernate 3.2.3.ga as JPA entity manager
JBossCache 1.4.1.SP3 as second level cache
We use annotations to define our mappings, example:
[code]
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
...
@Entity
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Table(name = "user",uniqueConstraints={@UniqueConstraint(columnNames={"name"})})
public class User extends BaseValueObject {
...
@ManyToMany (fetch=FetchType.LAZY)
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public Set<Right> getRights() {
return rights;
}
...
}
[/code]
NOTE: The 'Right' entity also has the @Cache annotation applied.
Sometimes we want to fetch the 'Right' collection of 'User' but sometimes not, example EJBQL with fetching:
[code]
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
...
@Stateless
@Local( { IConfigHelperBean.class })
public class ConfigHelperBean implements IConfigHelperBean {
@PersistenceContext(unitName = "sampleApp")
private EntityManager em;
public User getUserByNameWithFetchJoin(String userName) {
return em.createQuery("SELECT u FROM User u LEFT JOIN FETCH u.rights WHERE user.name = :userName").setParameter("userName", userName).setHint("org.hibernate.cacheable", new Boolean(true)).getSingleResult();
}
}
[/code]
The caching of the entities and the query seems to work correctly until we try to touch the user.rights collection after the EJB transaction has ended (and thus the EntityManager session is closed). We then are presented with the familiar LazyInitializationException as thrown by the PersistentSet implementation. This only happens when the query is executed for the second time and its results are in the second level cache (which we verified by inspecting the cache with the JBossCache MBean that is deployed in our JBoss AS). If we touch the 'rights' collection (by invoking its 'size' method) before the EJB transaction ends the LazyInitializationException is not thrown anymore. The MySql server log indicates no SQL queries are invoked anymore, this proves the second level cache works as it should.
Recently the following was posted on the hibernate.org main page
"28.04.2008 - Hibernate Core 3.3.0.CR1
This new release features:
* a redesign of the "second level cache" SPI
* a new integration with JBossCache 2.x taking full advantage of this new SPI (special thanks to Brian Stansberry for his help and hard work on this)
* introduction of the org.hibernate.jdbc.Work API for performing JDBC work without interfering with connection release modes
Additionally, this is the first release done from the new Maven project structure. The Maven artifacts are deployed to the JBoss Maven repository under the groupId org.hibernate. We also do still build a distribution bundle and upload it to SourceForge here."
Is there any hope Hibernate 3.3.0 will solve this longstanding major bug?
> LazyInitializationError on enabling query cache...
> --------------------------------------------------
>
> Key: HHH-1523
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1523
> Project: Hibernate3
> Issue Type: Bug
> Components: core
> Affects Versions: 3.0.5, 3.1
> Environment: 3.0.1 and 3.1, HSQLDB and Oracle
> Reporter: Vikas Sasidharan
> Attachments: cache_issue.log, QueryCacheIssue.zip
>
>
> I have two domain objects - Employee and Department - and there is a 1:N relationship from Department to Employee. When I join fetch an Employee with its Department, without query cache enabled, it works fine. If I enable query cache for this same query, it bombs with a LazyInitializationException.
> Notes:
> 1) We get this error only if query cache is enabled.
> 2) We observed the same behaviour on both oscache and ehcache
> 3) Calling Hibernate.initialize() explicitly after firing the HQL seems to work. The initialization does not fire an extra query though (it seems to pick it from the cache).
> 4) Setting "lazy=false" on the "many-to-one" mapping also works. However, it wouldn't be acceptable.
> Hibernate version: 3.0.5
> Mapping documents:
> Employee.hbm.xml
> <hibernate-mapping>
> <class name="tavant.platform.test.domain.Employee"
> table="CACHE_ISSUE_EMP" lazy="true" dynamic-update="true" dynamic-insert="true">
> <cache usage="read-write" />
> <id name="id" column="EMP_ID" type="java.lang.Long"
> access="field" unsaved-value="null">
> <generator class="increment" />
> </id>
>
> <property name="name" type="string" update="true"
> insert="true" column="EMP_NAME"/>
> <many-to-one name="department" class="tavant.platform.test.domain.Department"
> cascade="none" outer-join="auto" update="true" insert="true" column="DEPARTMENT_ID"/>
> </class>
> </hibernate-mapping>
>
> Department.hbm.xml
> <hibernate-mapping>
> <class name="tavant.platform.test.domain.Department" table="CACHE_ISSUE_DEP"
> lazy="true" dynamic-update="true" dynamic-insert="true">
>
> <cache usage="read-write" />
> <id name="id" column="DEPARTMENT_ID"
> type="java.lang.Long" access="field">
> <generator class="increment"/>
> </id>
> <property name="name" type="java.lang.String"
> update="false" insert="true" column="NAME"/>
> <bag name="employees" lazy="true"
> inverse="true" cascade="save-update" access="field">
> <cache usage="read-write"/>
> <key column="DEPARTMENT_ID"/>
> <one-to-many class="tavant.platform.test.domain.Employee"/>
> </bag>
> </class>
> </hibernate-mapping>
>
> Code between sessionFactory.openSession() and session.close():
> public Employee getEmployeeWithDepartment(String empName) {
> Session session = null;
> try {
> session = sessionFactory.openSession();
> Employee emp = (Employee) session.createQuery(
> "from Employee e join fetch e.department where e.name = :name")
> .setString("name", empName)
> .setCacheable(true)
> .uniqueResult();
> // If I uncomment the next line, this works (even without
> // firing an extra query)!
> // Hibernate.initialize(emp.getDepartment());
> return emp;
> } finally {
> if (session != null) {
> session.close();
> }
> }
> }
>
> // First load employee and populate cahces
> Employee emp = test.getEmployeeWithDepartment(EMPLOYEE_NAME);
> System.out.println("Employee : " + emp + ", Employee.Department : "
> + emp.getDepartment());
>
> // Now try to make use of the cache
> emp = test.getEmployeeWithDepartment(EMPLOYEE_NAME);
> System.out.println("Employee : " + emp + ", Employee.Department : "
> + emp.getDepartment());
>
> Full stack trace of any exception that occurs:
> org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
> at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:53)
> at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
> at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
> at tavant.platform.test.domain.Department$$EnhancerByCGLIB$$67b26899.toString(<generated>)
> at java.lang.String.valueOf(String.java:2131)
> at java.lang.StringBuffer.append(StringBuffer.java:370)
> at tavant.platform.test.client.TestPrefetchRelationWithQueryCacheEnabled.main(TestPrefetchRelationWithQueryCacheEnabled.java:116)
>
> Name and version of the database you are using:
> We have noticed this on Oracle and HSQL
> The generated SQL (show_sql=true):
> #First read, goes fine
> Hibernate: select employee0_.EMP_ID as EMP1_0_, department1_.DEPARTMENT_ID as DEPARTMENT1_1_, employee0_.EMP_NAME as EMP2_1_0_, employee0_.DEPARTMENT_ID as DEPARTMENT3_1_0_, department1_.NAME as NAME0_1_ from CACHE_ISSUE_EMP employee0_ inner join CACHE_ISSUE_DEP department1_ on employee0_.DEPARTMENT_ID=department1_.DEPARTMENT_ID where (employee0_.EMP_NAME=? )
> #Prints the Employee and Department fine
> Employee : [Id : 1, name : testEmployee], Employee.Department : [Id : 1, name : testDepartment]
> #Second read bombs!
> org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session was closed
> at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:53)
> at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
> at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
> [..]
> Please have a look at the post [http://forum.hibernate.org/viewtopic.php?t=955839] for more details and follow ups.
> Kindly help. I am attaching an Eclipse Project containing the TestCase. The main file is TestPrefetchRelationWithQueryCacheEnabled.
> Thanks,
> Vikas
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 6 months