I've got a problem where a lazy loaded collection is being initialized when retrieving data that was persisted as part of a previous transaction/session, but not initialized when retrieving information that has been saved within the currently open session.
Hibernate version: 3.0.1
Mapping documents:
I've got a UserGroup structure that allows a hierarchy based upon the parent user group:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://localhost/dev-box/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="com.devbox.entity.UserGroup"
table="USER_GROUP"
lazy="true"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="none"
>
<id
name="id"
column="id"
type="java.lang.Long"
>
<generator class="native">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-UserGroup.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
...non-pertinent mappings removed ...
<many-to-one
name="parentGroup"
class="com.devbox.entity.UserGroup"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="PARENT_GROUP_ID"
not-null="false"
/>
<bag
name="userGroups"
lazy="true"
inverse="true"
cascade="all-delete-orphan"
>
<key
column="PARENT_GROUP_ID"
>
</key>
<one-to-many
class="com.devbox.entity.UserGroup"
/>
</bag>
<filter name="enterpriseFilter" condition="(enterprise_id IS NULL OR enterprise_id = :enterpriseId)"/>
</class><filter-def name="enterpriseFilter"><filter-param name="enterpriseId" type="long" /></filter-def>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Unit Test Code:
Code:
// Session is opened in the Setup() method and closed in the tearDown() method
// Therefore, this method is wrapped in a session
public void testGetAllChildrenUserGroups() {
// The group called "Development" pre-exists in the database
UserGroup y = securityDAO.findUserGroupByName(
"Development");
assertFalse(y.getUserGroups().isEmpty());
UserGroup g = createUserGroup("Group", null);
UserGroup g1 = createUserGroup("Group1", g);
UserGroup g2 = createUserGroup("Group2", g);
UserGroup g1a = createUserGroup("Group1a", g1);
UserGroup g1b = createUserGroup("Group1b", g1);
securityDAO.save(g);
securityDAO.save(g1);
securityDAO.save(g1a);
securityDAO.save(g1b);
securityDAO.save(g2);
y = securityDAO.findUserGroupByName(
"Group");
// Hibernate.initialize(y.getUserGroups()); commented out, but didn't fix problem even when uncommented
assertFalse(y.getUserGroups().isEmpty()); // <== null pointer here
}
private UserGroup createUserGroup(String name, UserGroup parent) {
UserGroup userGroup = new UserGroup();
userGroup.setName(name);
userGroup.setParentGroup(parent);
return userGroup;
}
Full stack trace of any exception that occurs:Code:
java.lang.NullPointerException
at com.devbox.dao.hibernateimpl.SecurityDAOImplTest.testGetAllChildrenUserGroups(SecurityDAOImplTest.java:713)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:474)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:342)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:194)
Name and version of the database you are using:MySQL 4.1
The generated SQL (show_sql=true):Code:
[ generated after the first findUserGroupByName]
Hibernate: select usergroup0_.id as id, usergroup0_.ENTERPRISE_ID as ENTERPRISE2_31_, usergroup0_.PARENT_GROUP_ID as PARENT3_31_, usergroup0_.NAME as NAME31_, usergroup0_.CREATED_BY_USER_ID as CREATED5_31_, usergroup0_.create_timestamp as create6_31_, usergroup0_.UPDATED_BY_USER_ID as UPDATED7_31_, usergroup0_.update_timestamp as update8_31_ from USER_GROUP usergroup0_ where (usergroup0_.enterprise_id IS NULL OR usergroup0_.enterprise_id = ?) and usergroup0_.NAME=? and ((? is null) and (usergroup0_.ENTERPRISE_ID is null) or usergroup0_.ENTERPRISE_ID=?)
[ generated after the first getUserGroups.isEmpty()]
Hibernate: select usergroups0_.PARENT_GROUP_ID as PARENT3___, usergroups0_.id as id__, usergroups0_.id as id0_, usergroups0_.ENTERPRISE_ID as ENTERPRISE2_31_0_, usergroups0_.PARENT_GROUP_ID as PARENT3_31_0_, usergroups0_.NAME as NAME31_0_, usergroups0_.CREATED_BY_USER_ID as CREATED5_31_0_, usergroups0_.create_timestamp as create6_31_0_, usergroups0_.UPDATED_BY_USER_ID as UPDATED7_31_0_, usergroups0_.update_timestamp as update8_31_0_ from USER_GROUP usergroups0_ where usergroups0_.PARENT_GROUP_ID=?
Hibernate: insert into USER_GROUP (ENTERPRISE_ID, PARENT_GROUP_ID, NAME, CREATED_BY_USER_ID, create_timestamp, UPDATED_BY_USER_ID, update_timestamp) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_GROUP (ENTERPRISE_ID, PARENT_GROUP_ID, NAME, CREATED_BY_USER_ID, create_timestamp, UPDATED_BY_USER_ID, update_timestamp) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_GROUP (ENTERPRISE_ID, PARENT_GROUP_ID, NAME, CREATED_BY_USER_ID, create_timestamp, UPDATED_BY_USER_ID, update_timestamp) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_GROUP (ENTERPRISE_ID, PARENT_GROUP_ID, NAME, CREATED_BY_USER_ID, create_timestamp, UPDATED_BY_USER_ID, update_timestamp) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_GROUP (ENTERPRISE_ID, PARENT_GROUP_ID, NAME, CREATED_BY_USER_ID, create_timestamp, UPDATED_BY_USER_ID, update_timestamp) values (?, ?, ?, ?, ?, ?, ?)
[the second findUserGroupByName]
Hibernate: select usergroup0_.id as id, usergroup0_.ENTERPRISE_ID as ENTERPRISE2_31_, usergroup0_.PARENT_GROUP_ID as PARENT3_31_, usergroup0_.NAME as NAME31_, usergroup0_.CREATED_BY_USER_ID as CREATED5_31_, usergroup0_.create_timestamp as create6_31_, usergroup0_.UPDATED_BY_USER_ID as UPDATED7_31_, usergroup0_.update_timestamp as update8_31_ from USER_GROUP usergroup0_ where (usergroup0_.enterprise_id IS NULL OR usergroup0_.enterprise_id = ?) and usergroup0_.NAME=? and ((? is null) and (usergroup0_.ENTERPRISE_ID is null) or usergroup0_.ENTERPRISE_ID=?)
[ note no second call before npe...]
Note I've also checked in the database and all the records are created as I would expect.
I think this should work. Am I missing something? Any help would be appreciated.