Hi,
We are using Hibernate2.1.3 as a MBean in JBoss-3.2.3. We are running into issues related to lazy loading. We have set lazy=true on the collections of a parent objects. But, even then, when the parent object is loaded, the collection is also getting populated with the child objects. Following is a sample hbm mapping:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="com.dbdata.core.hibernateobject.Channel"
table="CM_TABLE"
>
<cache usage="transactional"/>
<composite-id name="id" class="com.dbdata.core.hibernateobject.ChannelId">
<key-property
name="id"
column="ID"
type="int"
length="22"
>
</key-property>
<key-property
name="versionId"
column="VERSION_ID"
type="int"
length="22"
>
</key-property>
</composite-id>
<timestamp
name="revisionDate"
column="REVISION_DTTM"
/>
<property
name="name"
type="java.lang.String"
column="NAME"
not-null="true"
length="40"
>
</property>
<property
name="description"
type="java.lang.String"
column="DESCRIPTION"
length="1000"
>
</property>
<!-- Associations -->
<set
name="channelInstances"
[b]lazy="true"[/b]
inverse="true"
cascade="all-delete-orphan"
order-by="NAME asc"
>
<cache usage="transactional"/>
<key>
<column name="CLASS_ID" />
<column name="CLASS_VERSION_ID" />
</key>
<one-to-many
class="com.dbdata.core.hibernateobject.ChannelInstance"
/>
</set>
</class>
</hibernate-mapping>
When we are loading the com.dbdata.core.hibernateobject.Channel (Parent) object, even the collection "channelInstances" is getting populated with instances of com.dbdata.core.hibernateobject.ChannelInstance.
We did a bit of investigation into this and tried to obtain a Thread dump from one of the setters of the child object, to find out the flow from where this setter of the child is getting called. Following is the output from the Thread.dumpStack() invoked from one of the setters of the child object:
Code:
2006-03-02 15:39:35,393 ERROR [STDERR] at [b]com.dbdata.core.hibernateobject.Channel.setChannelInstances[/b](Channel.java:301)
2006-03-02 15:39:35,393 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2006-03-02 15:39:35,393 ERROR [STDERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
2006-03-02 15:39:35,393 ERROR [STDERR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
2006-03-02 15:39:35,393 ERROR [STDERR] at java.lang.reflect.Method.invoke(Method.java:324)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:38)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.persister.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:221)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:2199)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.loader.Loader.doQuery(Loader.java:293)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:186)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:889)
2006-03-02 15:39:35,393 ERROR [STDERR] at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:909)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:59)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:51)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:419)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:2106)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:1980)
2006-03-02 15:39:35,409 ERROR [STDERR] at net.sf.hibernate.impl.SessionImpl.get(SessionImpl.java:1916)
It appears that while loading the parent(through Loader.loadEntity) Hibernate invokes the doQueryAndInitializeNonLazyCollections. We had a look at this code and it looks like it intializes the collection irrespective of whether it is lazy=true or lazy=false. Also, the javadoc of this method does not say anything about the lazy attribute:
Quote:
/**
* Execute an SQL query and attempt to instantiate instances of the class mapped by the given
* persister from each row of the <tt>ResultSet</tt>. If an object is supplied, will attempt to
* initialize that object. If a collection is supplied, attempt to initialize that collection.
*/
Are we missing something here? The lazy=true is a very fundamental feature and it appears that we are surely missing something in our configuration. Any help is appreciated.
Thank you.