-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: Lazy load collection
PostPosted: Thu Apr 01, 2004 8:43 pm 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
" Hibernate.initialize() for each collection that will be needed in the web tier (this call must occur before the session is closed) or retrieves the collection eagerly using a query with a FETCH clause. "

-> the mapping file indicates lazy=true for the collection
-> I retreive a collection using the fetch and the collection is empty
(no associations in the database)
-> the parent object is sent along with this empty collection to another layer of the app
-> the other layer of the app attempts to use the empty collections to see if anything exists in it
-> a lazy intialization exception is thrown

is this the correct behaviour ? I thought if u used the fetch it would not try and lazy intialize the collection again . Is there any way around this . It works fine is there are assications in the database .

Thanks again


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 01, 2004 9:41 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
I retreive a collection using the fetch and the collection is empty

Quote:
a lazy intialization exception is thrown


I don't believe you :)

Quote:
I thought if u used the fetch it would not try and lazy intialize the collection again


Of course.

Show the stack trace.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 01, 2004 10:38 pm 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
I will have the stack trace first thing in the morning

this is the query
select user from User user left join fetch user.Group.roles where user.userId = :pk

the table structure is as follows


USER >- GROUP -< GROUPROLE >- ROLE

user can belong to one group a group can have many roles


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 01, 2004 11:35 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Use

Code:
<many-to-many outer-join="true" ... >


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 10:21 am 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
tried the many to many .. it still does not work

this is the error

net.sf.hibernate.LazyInitializationException: Failed to lazily initialize a collection - no session or session was closed
at net.sf.hibernate.collection.PersistentCollection.initialize(PersistentCollection.java:214)
at net.sf.hibernate.collection.PersistentCollection.read(PersistentCollection.java:71)
at net.sf.hibernate.collection.Set.size(Set.java:106)
at on.gov.ij.opp.scms.junit.testcases.UserManagerTest.testfindByPk(UserManagerTest.java:132)
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:324)
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 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:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)



I was also always under the impression that

"HQL always ignores the mapping document outer join fetch setting"


I don't even see the SQL for the roles executing with the query I posted .. just one select for the user and once select for the group


Thanks again


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 10:28 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
Are you trying to acceed the lazy loaded collection AFTER the hibernate session is closed?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 10:38 am 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
// Find user (Session is opend and closed in findby pk ... using fetch in query)
User user = userManager.findByPk(pk);

// Should have intialized group object
user.getAssignedGroup();

// Should have intialized roles ... throws lazy exeception
user.getAssignedGroup().getRoles()

But as Gavin has posted , if u use a fetch it should not try a lazy intialize the the collection again .. meaning the user.getAssignedGroup().getRoles()
should not throw a lazy exception even if the collection is null .. meaning there are no associations in the database ?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 11:03 am 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
It works ! , I put the out-join inside the set as opposed to the many to many

<set name="roles" table="tblgrouprole" lazy="true" outer-join="true" >
<key column="groupid" />
<many-to-many class="Role"column="roleid" />
</set>

Thanks for all you fast replies , could somebody still explain this line

[/quote]HQL always ignores the mapping document outer join fetch setting , if you have mapped some association to be fetched by outer join (eg by setting outer-join="true" on the association mapping) , any HQL query will ignore this preference[quote]

I didn't put the outer-join in query cause I thought it would be ignored , I probably missing something with this statement .

Thanks again


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 3:54 pm 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
what I thought was working before is not .. sorry

here are my mapping files

<-------------- User Mapping ----------------------------->

<class name="User" optimistic-lock="version" table="tblUserDetail" >

<id name="userDetailId" column="userdetailid" type="int">
<generator class="sequence">
<param name="sequence">tbluserdetail_seq</param>
</generator>
</id>

<version column="version" name="version" />

<property name="name">
<column name="dn" sql-type="varchar2(1000)" />
</property>

<property name="isActive">
<column name="isActive" sql-type="number(32)" />
</property>

<property name="groupID" >
<column name="groupid" sql-type="number(32)" />
</property>


<many-to-one name="assignedGroup" class="Group" column="groupid" insert="false" update="false" />

</class>

<-------------------------------- Group Mapping ----------------------------->


<class name="Group" optimistic-lock="version" table="tblgroup" >

<id name="groupID" column="groupid" type="int" unsaved-value="0" >
<generator class="sequence">
<param name="sequence">tblgroup_seq</param>
</generator>
</id>

<version column="version" name="version" />

<property name="name">
<column name="name" />
</property>

<property name="description">
<column name="description"/>
</property>

<property name="isActive">
<column name="isActive" />
</property>


<set name="roles" table="tblgrouprole" outer-join="true" lazy="true" >
<key column="groupid" />
<many-to-many outer-join="true" class="Role" column="roleid" />
</set>

</class>


<----------------------------- Role Mapping -------------------------------->

<hibernate-mapping auto-import="true">

<class name="Role" table="tblrole">

<id name="roleId" column="roleId" type="int">
<generator class="sequence">
<param name="sequence">tblrole_seq</param>
</generator>
</id>

<property name="roleName">
<column name="name" />
</property>

<property name="roleDesc">
<column name="description" />
</property>

<set name="groups" table="tblgrouprole" lazy="true">
<key column="roleid" />
<many-to-many class="Group" column="groupid" outer-join="true" />
</set>

</class>


The problem once again is as follows ... now that I have outer-join=true
(Both problems assume a user exists in the database with an assigned group .. but the group has no assigned roles)

-> dao get user object by calling the following query
" select user from User user where user.userDetailId = :pk "
-> another tier attempts to access the roles .. user.getAssignedGroup.getRoles()
-> Since I did not use the fetch in query I would have thought for sure I would get a lazy exception .. but I don't .. it returns 0 as the size of the collection cause no associations exist in the database

Second senario

-> dao get user object by calling the following query
" select user from User user left join fetch user.assignedGroup.roles where user.userDetailId = :pk"
-> another tier attempts to access the roles .. user.getAssignedGroup.getRoles()
-> Since I used the fetch in query lazy intialization is by-passed and no exception is thrown .. perfect .. what I expected (still no associations exist in the database)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 02, 2004 4:13 pm 
Beginner
Beginner

Joined: Wed Feb 25, 2004 10:58 am
Posts: 43
if I take out the outer join in the set

then

-> dao get user object by calling the following query
" select user from User user where user.userDetailId = :pk "
-> another tier attempts to access the roles .. user.getAssignedGroup.getRoles()
-> Since I did not use the fetch it does THROW lazy exception .. what I thought


-> dao get user object by calling the following query
" select user from User user left join fetch user.assignedGroup.roles where user.userDetailId = :pk"
-> another tier attempts to access the roles .. user.getAssignedGroup.getRoles()
-> Since I did use the fetch I thought that it would not throw lazy exception but it does .





<class name="Group" optimistic-lock="version" table="tblgroup" >

<id name="groupID" column="groupid" type="int" unsaved-value="0" >
<generator class="sequence">
<param name="sequence">tblgroup_seq</param>
</generator>
</id>

<version column="version" name="version" />

<property name="name">
<column name="name" />
</property>

<property name="description">
<column name="description"/>
</property>

<property name="isActive">
<column name="isActive" />
</property>


<set name="roles" table="tblgrouprole" lazy="true" >
<key column="groupid" />
<many-to-many outer-join="true" class="Role" column="roleid" />
</set>

</class>


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.