-->
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.  [ 13 posts ] 
Author Message
 Post subject: Lazy collections
PostPosted: Mon Jun 05, 2006 8:59 am 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
If I have a collection inside a class (let's say "Country" has a collection of "States"), and the collection is marked as lazy-load... How do I reach that collection when I need it?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 05, 2006 11:16 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
there are several methods depending on how your application is architected. two of them are session.Lock(Country, LockMode.None) and NHibernateUtil.Initialize(country.States).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 05, 2006 11:31 am 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
congratulations! You've just become a beginner... and I think your post helped me, althoug I'll have to read more about session locking, starting with what it means and what it does!!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 05, 2006 11:42 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
session.Lock() associates an existing persistent object with a session. if you know the object hasn't been updated, then you use LockMode.None so no SQL SELECT is issued. If you think the object may have been modifiued, then you need to use LockMode.Read or LockMode.Upgrade to load the new persistent data from the database. then a simple call to myObject.Collection will load the collection with an open session. something like:

Code:
ISession session = new ISessionFactory.OpenSession();

session.Lock(myObject, LockMode.None);

foreach (Object o in myObject.Collection)
    do something;

session.Close();


this is a very basic way of looking at it...

-devon


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 05, 2006 7:25 pm 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
Just to try the "lock" method, I tryed this

Code:
        State rState = StateDAO.SelectOne(23); //fetches a State
        ISession session = Configurator.GetSessionFactory(typeof(State)).OpenSession();
        session.Lock(rState, LockMode.None);
        foreach (City rCity in State.Cities)
        {
            Response.Write("City: " + rCity.Name + "\n");
        }
        session.Close();


and I realized that as soon as I call "Lock", the lazy collection was loaded... but what if I have many lazy collections, and I only want "Cities" to be loaded?

Plus: Where can I find a good documentation about the "Lock" Method? I didn't see much in Hibernate's docs...


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 2:01 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
well there really isn't much more documentation than what is online, in the .chm file, the source code, and the Hibernate in Action book as far as I know. And they're all pretty close the the same terse notes on how to use it. Not alot about when and what situations.

Quote:
but what if I have many lazy collections, and I only want "Cities" to be loaded?


All session.Lock() really does is reassociate a detached object with a new session so basically you will only instantiate a lazy collection if you access it. this is the same behavior as if you are accessing the lazy collection in the same session that you originally loaded the object. more specifically:

Code:
Country c = (Country) session.Load(typeof(Country), 1);
foreach (State s in c.States)
    Console.Write(s.Name);
session.Close();


is basically the same (with regard to lazy loading) as:

Code:
Country c = (Country) session.Load(typeof(Country), 1);
session.Close;
...
sessionTwo.lock(c, LockMode.None);
foreach (State s in c.States)
    Console.Write(s.Name);

sessionTwo.Close();


in each instance, the c.States collection will be loaded because the Country object is attached to a session. No other lazily loaded collections would be loaded until they were accessed in a similar manner. this points to something I overlooked in answering your first question:

Quote:
If I have a collection inside a class (let's say "Country" has a collection of "States"), and the collection is marked as lazy-load... How do I reach that collection when I need it?


if you are accessing the collection in the same session that you originally loaded the object, NH will load the collection immediately. so unless you are closing the session before you are accessing the collection, your collection should be available the first time you use it.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 12:05 pm 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
I get it now, the problem was that I was using the debugger to watch the property and while doing that, I was forcing the load of my collection. I debugged step by step with step into and saw that the collection was not loaded and NHibernate loaded it... cool! Thanks again (like for the zillon time, between this and previous posts!!)

Alejandro.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 12:12 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
Alejandro,

no worries, i'm glad it is working for you.

OT:

are you ready for the world cup? i think this is going to be a great tournament.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 12:21 pm 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
I'm not a soccer fan, I don't watch any sports actually... but when the WC arrives, I may even watch Kamtchatka vs Tanzania, I don't care the team, I watch the game!
And I'm hoping this time Argentina's kicking Brazil's ass!!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 06, 2006 1:23 pm 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
I'm not a soccer fan, I don't watch any sports actually... but when the WC arrives, I may even watch Kamtchatka vs Tanzania, I don't care the team, I watch the game!
And I'm hoping this time Argentina's kicking Brazil's ass!!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 3:59 pm 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
There are a few useful tricks that you may or may not be aware of that are extremely helpful when working with NHibernate. Namely, you'll probably want to create a class that is basically a singleton that stores your Session object for a request, only, it won't be a true singleton, it'll be a singleton for a given thread. i.e. store the Session object in a variable marked [ThreadStatic]. This way you can share a Session through out all your code rather than creating sessions multiple times.

Also, if you're implementing a web app, something that is very useful to do is create an IHttpModule that closes the session at the end of the request. This way the session is always closed and the session is open until after all your UI code runs which may access properties/collections which may need to be lazily initialized.

These patterns are describe elsewhere on this site, although I'm not sure if there are .NET specific versions of the documents. i.e. you might need to translate them from Java to .NET which is what I did.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 4:57 pm 
Regular
Regular

Joined: Sun Feb 12, 2006 10:18 pm
Posts: 60
Location: Rosario, Argentina
Coincidentally, someone sent me this link yesterday (as an answer to another question I posted)

http://www.codeproject.com/aspnet/NHibe ... mid=278860


It explains how to do what you are saying, and gives an example. Actually, it implements a "Open-Session-in-View" Pattern. I'm analything using the classes in my project.

Also, a note to everyone else that posted an answer to my original question: here is an article explaining the opn-view-in-session, and mentions why you shouldn't load lazy-load collections in different sessions:

http://www.hibernate.org/43.html

and a post in the forum, too:

http://forum.hibernate.org/viewtopic.php?t=927886


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 07, 2006 5:09 pm 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
One of these days it seems like these helper classes should be included in the NHibernate distribution itself (the same is true for Hibernate). To me, it doesn't make sense that everyone should have to implement this on their own. It seems like it's so often used that a solid implementation of it should be implemented and included by default.


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