Hibernate version: 2.1.6
Mapping documents:
Code:
<class name="Parent" table="parent">
....
<set name="children" inverse="true" lazy="true" cascade="none">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
</class>
<class name="Child" table="child">
....
<set name="grandChildren" inverse="true" lazy="true" cascade="none">
<key column="child_id"/>
<one-to-many class="GrandChild"/>
</set>
<many-to-one name="parent" class="Parent" column="parent_id"/>
</class>
<class name="GrandChild" table="grand_child">
....
<many-to-one name="parent" class="Child" column="child_id"/>
</class>
Code between sessionFactory.openSession() and session.close():Please see below
Full stack trace of any exception that occurs:net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
(Please see below)
Name and version of the database you are using:MySQL 4.0.18
The generated SQL (show_sql=true):N/A
Debug level Hibernate log excerpt:N/A
This is about LazyInitializationException; I understand the need to have an open Hibernate session to access objects in a lazily loaded collection, but this problem is still puzzling to me. Your advice is greatly appreciated!
I have a 2-level hierarchy of parent-child-grandchild relationship as follows:
* A Parent object contains a Set of Child objects
* A Child object contains a Set of GrandChild objects
* Both sets are lazily loaded
My console application first reads in a Parent object from session 1, and closes the session.
It then reassociates the Parent object to session 2, and successfully accesses the set of Child objects; it goes on to access all the GrandChild objects contained in all the Child objects.
And this all works fine. The code looks like the following:
Code:
session1 = // obtain a session ...
Parent parent = (Parent) session1.get(...);
session1.close();
session2 = // obtain another session ...
session2.lock(parent, LockMode.NONE);
Iterator it = parent.getChildren().iterator();
while (it.hasNext()) {
Child child = (Child) it.next();
// getGrandChildren() returns a Set of GrandChild objects
System.out.println(child.getGrandChildren().size());
}
Now, I just add one line to the above code, and it generates the famous "Failed to lazily initialize a collection - no session or session was closed" exception:
Code:
session1 = // obtain a session ...
Parent parent = (Parent) session1.get(...);
// --- ADD THE LINE BELOW ---
// getChildren() returns a Set of Child objects
System.out.println(parent.getChildren().size()); // load all children
session1.close();
session2 = // obtain another session ...
session2.lock(parent, LockMode.NONE);
Iterator it = parent.getChildren().iterator();
while (it.hasNext()) {
Child child = (Child) it.next();
// getGrandChildren() returns a Set of GrandChild objects
System.out.println(child.getGrandChildren().size()); // *** EXCEPTION ***
}
I thought that the Session.lock(Object, LockMode) method reassociates an object and all objects reachable from that object (such as children and grandchildren) to the new session, and the first program seems to prove just that.
However, in the second program, just because I physically loaded all children of the parent in the first session, I have to also reassociate all the Child objects individually to session2 before I can access grandchildren.
So my question is: does lock() method reassociate the object and all its children and grandchildren, or I have to always manually associate each child?
Thanks a lot for your advice!