-->
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.  [ 14 posts ] 
Author Message
 Post subject: Lazy loading not working
PostPosted: Wed Mar 03, 2004 11:32 pm 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
With the mapping below, I always get all children objects loaded. Is there a reason that lazy-loading isn't happening?

I'm using Hibernate 2.1, and I'm using session.find("from Parent as p") to load the parent.

Any suggesions?

-Mitch
Code:
<hibernate-mapping>
    <class name="Parent" table="PARENT" lazy="true">
        <id .../>
        <list name="children" cascade="all-delete-orphan"
              inverse="true" lazy="true" outer-join="true">
            <key column="PARENT_ID"/>
            <index column="SEQ"/>
            <one-to-many class="Child"/>
        </list>
    </class>

    <class name="Child"  table="CHILD" lazy="true">
        <id.../>
        <many-to-one column="PARENT_ID" name="parent"/>
        <property column="SEQUENCE" name="sequence"/>
        <property column="X" name="x"/>
     </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 03, 2004 11:59 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
change outer-join="true" to outer-join="false" on your <list> definition for the children attribute of Parent.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 11:23 am 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
Thanks for the response, but unfortunately, changing outer-join from 'true' to 'false' had no affect.

With lazy loading, it seems to me I shouldn't get the child records until until I access Parent.getChildren().

Here is the section of the logged SQL demonstrating the problem:
Code:
Hibernate: select parent0_.ID as ID__, from PARENT parent0_ where parent0_.DETAIL_ROW_ID=?
Hibernate: select child0_.ID as ID__, child0_.parent_ID as parent_ID__, child0_.SEQUENCE as SEQUENCE__, child0_.ID as ID0_, child0_.parent_ID as parent_ID0_, child0_.SEQUENCE as SEQUENCE0_, child0_.X as X0_, from CHILD child0_ where child0_.PARENT_ID=?
Hibernate: select child0_.ID as ID__, child0_.parent_ID as parent_ID__, child0_.SEQUENCE as SEQUENCE__, child0_.ID as ID0_, child0_.parent_ID as parent_ID0_, child0_.SEQUENCE as SEQUENCE0_, child0_.X as X0_, from CHILD child0_ where child0_.PARENT_ID=?
Hibernate: select child0_.ID as ID__, child0_.parent_ID as parent_ID__, child0_.SEQUENCE as SEQUENCE__, child0_.ID as ID0_, child0_.parent_ID as parent_ID0_, child0_.SEQUENCE as SEQUENCE0_, child0_.X as X0_, from CHILD child0_ where child0_.PARENT_ID=?
Hibernate: select child0_.ID as ID__, child0_.parent_ID as parent_ID__, child0_.SEQUENCE as SEQUENCE__, child0_.ID as ID0_, child0_.parent_ID as parent_ID0_, child0_.SEQUENCE as SEQUENCE0_, child0_.X as X0_, from CHILD child0_ where child0_.PARENT_ID=?
Hibernate: select child0_.ID as ID__, child0_.parent_ID as parent_ID__, child0_.SEQUENCE as SEQUENCE__, child0_.ID as ID0_, child0_.parent_ID as parent_ID0_, child0_.SEQUENCE as SEQUENCE0_, child0_.X as X0_, from CHILD child0_ where child0_.PARENT_ID=?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 11:26 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
have you a breakpoint on
session.find("from Parent as p") ???

as you tell the first sql executed is
Hibernate: select parent0_.ID as ID__, from PARENT parent0_ where parent0_.DETAIL_ROW_ID=?

Aren't you copying attribute to another object after?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 11:47 am 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
Yes, I do set a breakpoint and single-step over the find() method.

Before the
Code:
(Parent)s.find("from Parent as p").get(0);
method returns, I see the logged SQL that loads all associated Child records.

Here is the actual code:
Code:
public void testRead() throws Exception {
    Session s = HibernateSession.getCurrent();
    Parent p = (Parent) s.find("from Parent as p").get(0);
    HibernateSession.releaseSession();
}


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 12:10 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
try
<many-to-one column="PARENT_ID" outer-join="false" name="parent"/>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 12:19 pm 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
I've found the cause of the non-lazy loads, but I'm not sure I understand why.

It turns out that another developer added a call to an init() method inside the Parent() constructor. Inside this init() method they are doing the following:
Code:
children = new ArrayList();


For some reason, this forces Hibernate to load all children from the database. I'm looking into alternatives to setting the children List in the constructor, but can someone elaborate on why this disables lazy-loading?

Thanks,
-Mitch


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 1:11 pm 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
children is the property you want to lazy load.
It's null since you don't "hit" the property.
By doing children = ...., you're hitting the property so it is loading...

You may not do such thing in the constructor


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 6:45 pm 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
Ok. Lazy-loading is working in my JUnit test, but I still get all children loaded in my application (i.e. no change).

I have isolated the operative statement as:
Code:
for (Iterator i = RootObj.getParents().iterator(); i)


As soon as I step over this line, I get the entire set of child records in addition to the Parent records. I have actually traced this into the .iterator() method.

So I may have a simple question, will something about this access method cause lazy-loading between the Parent->Child to be ignored?

-Mitch


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 8:28 pm 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
Sure enough. Even in my JUnit test. If I call iterator() on the collection of parent objects, Hibernate loops through and loads all Child objects, regardless of the fact that they are supposed to be loaded lazily (i.e. when needed).

Is this correct behavior?

-Mitch


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 04, 2004 11:32 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Of course. Its the collection itself thats lazy loaded, not the elements of the collection. As soon as you call any method on that lazy collection, the elements of that collection are loaded.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 1:12 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
This is absolutely correct behavior for a one-to-many (just think about it), many-to-many is a different matter.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 10:45 am 
Regular
Regular

Joined: Wed Sep 03, 2003 9:56 pm
Posts: 58
But the elements (in this case, Parent objects) also have a one-to-many mapping to Child objects. I agree that all Parent objects should be loaded, but I don't want each Parent's Child objects (they are never used), but they come anyway.

If I do a s.find() on any single Parent object I don't get the children. If I call iterate() on the collection of Parent objects, Hibernate loads all Parent objects (this is ok) *and* all associated Child objects (this is what I don't want, but can't seem to prevent).


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2004 10:50 am 
Hibernate Team
Hibernate Team

Joined: Thu Dec 18, 2003 9:55 am
Posts: 1977
Location: France
have you removed the code that was in the constructor?
give latest version of your mapping file and the query your are coding


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 14 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.