-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: lazy="false" on class element
PostPosted: Wed Feb 13, 2008 6:48 am 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
I'd like a clarification about what effect exactly does adding a lazy="false" attribute to a class element (in a NHibernate 1.2.1 mapping file) have? I assumed it meant that all properties and collections of that class would be eagerly loaded. However I just ran into a situation where, in spite of the class's lazy="false" attribute, a set collection of that class was being lazily loaded.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 7:02 am 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
Hi,

When you mark the class as lazy (default), NHibernate do a proxy with your class to lazy-loading the collections. To this issue, all properties still loaded eagerly.

When you don't mark as lazy (non-default: lazy="false") NHibernate don't make a proxy, and the whole class y loaded eagerly.

NHibernate doesn't support yet lazy-property:
http://www.hibernate.org/hib_docs/v3/re ... properties

Best regards

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 6:47 pm 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
Thanks for the reply but it doesn't explain the behaviour I've observed. I should have been more specific by including a code sample, so here is one below.
Code:
<class name="Category" lazy="false">
   <id name="ID"><generator class="native"/></id>
   <set name="SubCategories" inverse="true" cascade="all-delete-orphan">
      <key column="ParentCategoryID"/>
      <one-to-many class="Category"/>
   </set>
   <many-to-one name="ParentCategory" column="ParentCategoryID"/>
</class>

In this real example (from my current project), the SubCategories collection (whose items are also of type 'Category') is being eagarly loaded, in spite of the class's lazy="false" attribute. To solve this problem I added lazy="false" to the set element. But why was that necessary?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 8:58 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
Take a look on this class:
http://unhaddins.googlecode.com/svn/bra ... Fixture.cs

This code:
Code:
         using (new SqlLogSpy())
         using (ISession s = OpenSession())
         {
            IList<Cat> catsFound = s.CreateQuery("from Cat c where size(c.Kittens) > 0").List<Cat>();

            foreach (Cat cat in catsFound)
            {
               log.Debug(">>> Cat: " + cat.Name);

               // Tell NH we want the kittens, so hitting the db is needed.
               foreach (Cat kitten in cat.Kittens)
               {
                  log.Debug(">>>       Kitten: " + kitten.Name);
               }
            }
         }


Reproduce this output:
Code:
2008-02-13 22:38:53,718 DEBUG SQL:386 - select cat0_.Id as Id0_, cat0_.Name as Name0_ from Cat cat0_ where ((select count(*) from Cat kittens1_ where cat0_.Id=kittens1_.ParentId)>0 )
2008-02-13 22:38:59,906 DEBUG TestCase:57 - >>> Cat: Parent number 0
2008-02-13 22:39:16,421 DEBUG SQL:386 - SELECT kittens0_.ParentId as ParentId__1_, kittens0_.Id as Id1_, kittens0_.Id as Id0_0_, kittens0_.Name as Name0_0_ FROM Cat kittens0_ WHERE kittens0_.ParentId in (@p0, @p1, @p2); @p0 = '1', @p1 = '3', @p2 = '5'
2008-02-13 22:39:18,796 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 0
2008-02-13 22:39:24,843 DEBUG SQL:386 - SELECT kittens0_.ParentId as ParentId__1_, kittens0_.Id as Id1_, kittens0_.Id as Id0_0_, kittens0_.Name as Name0_0_ FROM Cat kittens0_ WHERE kittens0_.ParentId in (@p0, @p1, @p2); @p0 = '2', @p1 = '4', @p2 = '6'
2008-02-13 22:39:28,171 DEBUG TestCase:57 - >>> Cat: Parent number 1
2008-02-13 22:39:28,171 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 1
2008-02-13 22:39:28,765 DEBUG TestCase:57 - >>> Cat: Parent number 2
2008-02-13 22:39:28,765 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 2
2008-02-13 22:39:29,234 DEBUG TestCase:57 - >>> Cat: Parent number 3
2008-02-13 22:39:29,234 DEBUG SQL:386 - SELECT kittens0_.ParentId as ParentId__1_, kittens0_.Id as Id1_, kittens0_.Id as Id0_0_, kittens0_.Name as Name0_0_ FROM Cat kittens0_ WHERE kittens0_.ParentId in (@p0, @p1, @p2); @p0 = '7', @p1 = '9', @p2 = '11'
2008-02-13 22:39:29,250 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 3
2008-02-13 22:39:30,531 DEBUG TestCase:57 - >>> Cat: Parent number 4
2008-02-13 22:39:30,546 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 4
2008-02-13 22:39:30,546 DEBUG TestCase:57 - >>> Cat: Parent number 5
2008-02-13 22:39:30,546 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 5
2008-02-13 22:39:30,546 DEBUG TestCase:57 - >>> Cat: Parent number 6
2008-02-13 22:39:30,546 DEBUG SQL:386 - SELECT kittens0_.ParentId as ParentId__1_, kittens0_.Id as Id1_, kittens0_.Id as Id0_0_, kittens0_.Name as Name0_0_ FROM Cat kittens0_ WHERE kittens0_.ParentId in (@p0, @p1, @p2); @p0 = '13', @p1 = '8', @p2 = '10'
2008-02-13 22:39:30,562 DEBUG TestCase:62 - >>>       Kitten: Kitten of cat 6
2008-02-13 22:39:30,750 DEBUG TestCase:98 - TearDown


As you can see... the parent go for the kittens at iteration time.

The class and mapping you can find here:
http://unhaddins.googlecode.com/svn/bra ... /LazyLoad/

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 9:06 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
I mean, with lazy="true" the class never can get the child early, always do as lazy.

Best regards.

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 10:16 pm 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
Actually, this isn't providing me with the clarity I was seeking. Could someone please answer my original question? Looking at the (short) sample code included in my second post to this thread, why is the SubCategories set not being eagerly loaded (which is what I need)?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 10:44 pm 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
Original question:
Quote:
I'd like a clarification about what effect exactly does adding a lazy="false" attribute to a class element (in a NHibernate 1.2.1 mapping file) have?


Answer:
NHibernate doesn't proxy the class. Non lazy-loading behavior. When you Get/Load an object, it get fill with data.

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 10:51 pm 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
That still doesn't explain the behaviour I observed. I don't know how much more explicit I can get with my question. Is there any chance someone else could jump in here?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 11:00 pm 
Newbie

Joined: Thu Dec 21, 2006 1:41 pm
Posts: 4
I think you should be missing something there, could you please upload a test to the jira so we can check ?
If you still have troubles with this, I will try to commit some examples to uNHAddIns about Lazy Load.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 11:27 pm 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
Is that not the expected behaviour? Maybe the answer I'm seeking is that a class's lazy="false" attribute does not affect collections which contain instances of that class. Would someone please verify whether that is correct or not? If that is the case, then please tell me precisely what a class's lazy="false" attribute does affect.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 12:06 am 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
The default lazy value is always "true".

lazy=true -> class
lazy=true -> collection
then: lazy load on collection

lazy=false -> class
lazy=true -> collection
then: lazy load on collection

[nothing] -> class
[nothing] -> collection
then: lazy load on collection (is the default case)

[nothing] -> class
lazy=true -> collection
then: lazy load on collection

lazy=true -> class
[nothing] -> collection
then: lazy load on collection

lazy=false -> class
[nothing] -> collection
then: lazy load on collection

lazy=false -> class
lazy=false -> collection
then: Non-lazy load on collection

... an so on.


Remember that you can configurate the mapping with default-lazy=false and avoid all this matter.

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 12:46 am 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
That explains the effect upon collections (e.g. SubCategories) that contain instances of the class (e.g. Category) which has a lazy="false" in it's declaration. So what about many-to-one and one-to-one declarations that map to that class? Perhaps for those ones you could construct the same sort of table as you did above (although you may omit the [nothing] cases since we already know that [nothing] is the same as lazy="true").


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 1:32 am 
Regular
Regular

Joined: Tue Dec 25, 2007 3:41 pm
Posts: 57
Location: Argentina
Quote:
So what about many-to-one and one-to-one declarations that map to that class?


NH doesn't support property-laziness yet.

Best regards

_________________
Dario Quintana


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 14, 2008 4:39 am 
Beginner
Beginner

Joined: Fri Sep 28, 2007 9:50 pm
Posts: 34
In Hibernate terminology, "property" implies value-type as opposed to reference-type. Therefore, many-to-one and one-to-one declarations are NOT properties. NH does support lazy loading for many-to-one and one-to-one declarations. That's the basic purpose of the Castle.DynamicProxy library. If it didn't, then what would NH support lazy loading on (other than collections, which is a different matter)?

Could someone else who's perhaps more familiar with NH please jump in sometime soon?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 12:38 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
The lazy property on the class itself affects the loading of the classes properties. There are cases where they are still loaded eagerly (Load() or Get(), I think, and when they are loaded as members of a collection). NHibernate accomplishes this by using a runtime class inherited from your class (this is why NH insists that all properties be declared virtual--it overrides them with versions that perform the load from the DB when they are accessed).

Collection laziness is independent of class laziness.

Does this answer your question?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

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.