Hello,
My problem would seem like an FAQ, but I've spent two days going through the forum for a solution and haven't found one.
I use Hibernate 2.1 and Oracle 9i, and a simple command line program.
I have the following mapping, with the class HeaderImpl associated with 3 collections of child entities: child1List,
child2List, child3List.
For performance reasons, I would like to load the child2 and child3 lists lazily.
But what I observe is that even though I indicate lazy="true" in all the collection declarations, when I call
header.getAttr1(), hibernate loads the object graphs of all the child entities (down to children of the child2 and child3).
<hibernate-mapping package="testApp">
<class name="Root" dynamic-insert="true" dynamic-update="true" table="ROOT">
<id name="ID">
<column name="ID" sql-type="NUMBER(15)"/>
<generator class="assigned"/>
</id>
<!-- versioning attribute for defining the version of an instance -->
<timestamp name="lastModifiedDate" column="TIME_STAMP"/>
<property name="createDate" column="S_ROT_CREATE_DATE"/>
</class>
<joined-subclass name="Header" dynamic-insert="true" dynamic-update="true" extends="Root" lazy="true" table="Header">
<key column="OBJ_ID"/>
<property name="attr1" column="ATTR_1" length="30"/>
<property name="attr2" column="ATTR_2" length="30"/>
<property name="attr3" column="ATTR_3" length="255"/>
<property name="status">
<column name="STATUS" sql-type="NUMBER(10)"/>
</property>
<many-to-one name="owner" class="User" column="OWNER_USER" cascade="none"/>
<many-to-one name="createdBy" class="User" column="CREATED_BY" cascade="none"/>
<bag name="child1List" cascade="all">
<key column="HEADER_ID"/>
<one-to-many class="Child1"/>
</bag>
<bag name="child2List" lazy="true" cascade="all">
<key column="HEADER_ID"/>
<one-to-many class="Child2"/>
</bag>
<bag name="child3List" lazy="true" cascade="all">
<key column="HEADER_ID"/>
<one-to-many class="Child3"/>
</bag>
</joined-subclass>
<class name="Child1" dynamic-insert="true" dynamic-update="true" lazy="true" table="CHILD1">
<property name="child_attr1" column="ATTR_1" length="30"/>
<property name="child_attr2" column="ATTR_2" length="30"/>
<property name="child_attr3" column="ATTR_3" length="255"/>
<property name="child_attr4" column="ATTR_3" length="60"/>
</class>
<class name="Child2" dynamic-update="true" lazy="true" table="CHILD2">
...
collections of Child3
...
</class>
<class name="Child3" dynamic-update="true" lazy="true" table="CHILD3">
...
collections of Child3
...
</class>
<class name="User" mutable="false" lazy="true" table="USER">
...
</class>
</hibernate-mapping>
Application code:
Header header = (Header)session.load(Header.class, id); // does not fire a query: a proxy is returned
String attr1 = header.getAttr1(); // this call causes Hibernate to issue large number of queries
// to load almost the entire object graph, down to the leaf level
// of child2 and child3.
// However, many-to-one associations of Header are not loaded.
Hibernate log (segment):
09:47:39,728 DEBUG SessionImpl:2198 - resolving associations for [testApp.Header#226112]
09:47:39,728 DEBUG SessionImpl:1982 - loading [testApp.User#173340]
09:47:39,728 DEBUG SessionImpl:1982 - loading [testApp.User#173340]
09:47:39,728 DEBUG SessionImpl:3929 - creating collection wrapper:[testApp.Header.child1List#226112]
09:47:39,743 DEBUG SessionImpl:3929 - creating collection wrapper:[testApp.Header.child2List#226112]
09:47:39,743 DEBUG SessionImpl:3929 - creating collection wrapper:[testApp.Header.child3List#226112]
09:47:39,759 DEBUG SessionImpl:3256 - initializing collection [testApp.Header.child1List#226112]
09:47:39,759 DEBUG SessionImpl:3257 - checking second-level cache
09:47:39,759 DEBUG SessionImpl:3263 - collection not cached
09:47:39,759 DEBUG BatcherImpl:196 - about to open: 0 open PreparedStatements, 0 open ResultSets
09:47:39,759 DEBUG SQL:237 - select child1....
09:47:39,775 DEBUG BatcherImpl:241 - preparing statement
...
Can someone point out what is wrong here?? Child1 should not be initialized at all.
Another thing. All my entity classes are generated using JAXB, which uses a wrapper List implementation, com.sun.xml.bind.util.ListImpl. Can this cause the strange behaviour??
Thank you
|