Hibernate version: 2
I have a recursive one-to-many tree structure that needs to be walked from top-to-bottom. In walking the tree, I use the following code (simplified):
Inside service bean:
Code:
public Document getOrgGroupDocument() {
...
// rootOrgGroupList has 1 item in it
List<OrgGroup> rootOrgGroupList = getRootOrgGroupList();
addOrgGroupElements(rootOrgGroupList, doc);
...
}
private void addOrgGroupElements(List<OrgGroup> orgGroupList, Document doc)
{
for (int i = 0; i < orgGroupList.size(); i++) {
OrgGroup orgGroup = orgGroupList.get(i);
...
addOrgGroupElementByUser(orgGroup.getChildOrgGroups(), doc);
...
}
}
Mapping documents:Code:
@Entity
@Table(name = "FL_ORG_GROUP")
public class OrgGroup
{
...
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "PARENT_OID", referencedColumnName = "CHRONICLE_OID")
public List<OrgGroup> getChildOrgGroups()
{
return childOrgGroup;
}
...
}
Session management:I'm using org.springframework.orm.hibernate3.support.OpenSessionInViewFilter and org.springframework.transaction.interceptor.TransactionProxyFactoryBean to proxy my service bean.
applicationContext.xml:
Code:
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/FrontlineDS"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="jndiDataSource"/>
<property name="configLocation" value="hibernate.cfg.xml"/>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="homeAmImpl" class="model.module.home.HomeModuleImpl">
<property name="orgGroupMgr" ref="orgGroupManager"/>
</bean>
<bean id="homeAm"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="homeAmImpl"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="orgGroupManager"
class="com.frontlinemci.model.entity.orggroup.OrgGroupManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
Problem:Stepping through with the debugger (and as you can see in the log output below), getRootOrgGroupList() fires off "FROM OrgGroup WHERE parentOid IS NULL", then the recursive method gets called for the first time. orgGroup.getChildOrgGroups() is lazy loaded (annotation shown above) and on the 2nd recursive call orgGroupList gets loaded with "load one-to-many model.entity.orggroup.OrgGroup.childOrgGroup". Finally, on the 3rd recursive call, when orgGroupList.size() gets called, Hibernate throws a LazyInitializationException.
It seems very strange to me that this exceptions occurs the 2nd time the lazy collection is used, NOT the first time. I'm afraid this may indicate there is something fundamentally wrong with my session handling, but I've been over the documentation again and again. Any help or suggestions is greatly appreciated.
Code:
Hibernate: /* FROM OrgGroup WHERE parentOid IS NULL */ select orggroup0_.ROW_OID as ROW1_47_, orggroup0_.CHRONICLE_OID as CHRONICLE2_47_, orggroup0_.CREATED_BY as CREATED3_47_, orggroup0_.MODIFIED_BY as MODIFIED4_47_, orggroup0_.VALID_BEGIN_DT as VALID5_47_, orggroup0_.VALID_END_DT as VALID6_47_, orggroup0_.DESC_TX as DESC7_47_, orggroup0_.ORG_GROUP_ID as ORG8_47_, orggroup0_.PARENT_OID as PARENT9_47_, orggroup0_.PRIMARY_CONTACT_OID as PRIMARY10_47_, orggroup0_.UOS_TOTAL_FL as UOS11_47_ from FL_ORG_GROUP orggroup0_ where (orggroup0_.PARENT_OID is null)
Hibernate: /* load one-to-many com.frontlinemci.model.entity.orggroup.OrgGroup.childOrgGroup */ select childorggr0_.PARENT_OID as PARENT9_1_, childorggr0_.ROW_OID as ROW1_1_, childorggr0_.ROW_OID as ROW1_47_0_, childorggr0_.CHRONICLE_OID as CHRONICLE2_47_0_, childorggr0_.CREATED_BY as CREATED3_47_0_, childorggr0_.MODIFIED_BY as MODIFIED4_47_0_, childorggr0_.VALID_BEGIN_DT as VALID5_47_0_, childorggr0_.VALID_END_DT as VALID6_47_0_, childorggr0_.DESC_TX as DESC7_47_0_, childorggr0_.ORG_GROUP_ID as ORG8_47_0_, childorggr0_.PARENT_OID as PARENT9_47_0_, childorggr0_.PRIMARY_CONTACT_OID as PRIMARY10_47_0_, childorggr0_.UOS_TOTAL_FL as UOS11_47_0_ from FL_ORG_GROUP childorggr0_ where childorggr0_.PARENT_OID=?
Aug 8, 2007 10:38:33 AM org.hibernate.LazyInitializationException <init>
SEVERE: failed to lazily initialize a collection of role: model.entity.orggroup.OrgGroup.childOrgGroup, no session or session was closed