-->
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.  [ 9 posts ] 
Author Message
 Post subject: Lazy Initialization Question
PostPosted: Thu Mar 30, 2006 2:16 pm 
Newbie

Joined: Thu Mar 30, 2006 2:10 pm
Posts: 14
Hibernate version: 1.0.2.0

Microsoft .NET version: 1.1

Hello,

I'm new to NHibernate, and one of the biggest things I have noticed so far is the lazy initialization of relational objects. While I agree that it is a good practise to get the current state of the objects from the database, what about the less important objects that are guareentied to always be (somewhat) the same?

For instance, when I have object A returned from the database, and I decide to store this object in session (for datagrid purposes) ... when I later attempt to resolve A.B, I can no longer access B due to the session being closed.

Is there a method I can work around this? I know this isn't an ideal situation, but I'm working with legacy here :)

Any comments or help would be greatly appreciated!

Cheers,
Timothy Grant Vogelsang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 30, 2006 7:09 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
look at setting up your second level cache for READ only data. The 2nd level stays around across sessions...


By the way, LAZY is slightly different than you thinking of.. it is not to get the most recent info from the database, you'd use select-before-update flag on your class object; and coupled with versioning, you are guaranteed never any stale data (nor updating stale data) - however, this comes with a cost - you have to select prior to update.. all your data.

LAZY simply means that a proxy object will be provided in place of your real object and the object itself will be intialized with the data upon first access to the object itself.

Thus you can defer loading of child objects this way, in case you are only interested in seeing the parent data.

also one last thing - don't keep (save) your "session" objects for reuse by web-requests - do a session-per-request pattern. Session is a logical unit of work. The only exception to this is when you'd actually like to have a long-running session - ie, a shopping cart for a single user.... then store the hib session in a http session object and reuse as the user browses.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 30, 2006 7:19 pm 
Newbie

Joined: Thu Mar 30, 2006 2:10 pm
Posts: 14
Thanks for taking the time to answer my question jt_1000.

jt_1000 wrote:
look at setting up your second level cache for READ only data. The 2nd level stays around across sessions...


Would you happen to have a link or resource handy that I can look into?

jt_1000 wrote:
By the way, LAZY is slightly different than you thinking of.. it is not to get the most recent info from the database, you'd use select-before-update flag on your class object; and coupled with versioning, you are guaranteed never any stale data (nor updating stale data) - however, this comes with a cost - you have to select prior to update.. all your data.

LAZY simply means that a proxy object will be provided in place of your real object and the object itself will be intialized with the data upon first access to the object itself.

Thus you can defer loading of child objects this way, in case you are only interested in seeing the parent data.

also one last thing - don't keep (save) your "session" objects for reuse by web-requests - do a session-per-request pattern. Session is a logical unit of work. The only exception to this is when you'd actually like to have a long-running session - ie, a shopping cart for a single user.... then store the hib session in a http session object and reuse as the user browses.


I have a hibernate session per request using the start-end request idea. Are you suggesting that it is also "possible" to store the hib session in a http session?

Thanks again,
Timothy Grant Vogelsang


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 30, 2006 7:30 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
check out pg 179 of reference.pdf to setup 2nd level cache.
http://www.hibernate.org/hib_docs/v3/reference/en/pdf/hibernate_reference.pdf

Yes you can keep the session around as long as you know the consequences... which are basically that any data you suck into the "session" is considered a snap-shot of the database. If you want to prevent multiple sessions from updating same object, then you'll need to setup versioning in your class mappings.

You can manage objects in your session with session.refresh(object0 or session.evict (object or collection). to help in keeping data clean. manage with diligence.

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 30, 2006 8:05 pm 
Newbie

Joined: Thu Mar 30, 2006 2:10 pm
Posts: 14
jt_1000 wrote:
check out pg 179 of reference.pdf to setup 2nd level cache.
http://www.hibernate.org/hib_docs/v3/reference/en/pdf/hibernate_reference.pdf


I browsed over the 2nd level cache documentation, but I'm a little confused how it works, all I would need to do is insert a <cache>...</cache> statement within my class that I would like to retrieve after the session has closed?

Thanks again, if you have any additional information or examples I would greatly appreciate it.

Timothy Grant Vogelsang


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 1:07 am 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
here is the quick cliff-notes to 2nd level cache...

1) you must setup a cache-provider in your hibernate.properties - choose ehCache.
2) you must specify what you want to cache - The two things that you can cache directly in the 2nd level are: Objects and Collections - if you cache objects, then basically it is an index by it's ID (either by <id> tag or by the hashCode method on your java class, if provided) into a table of objects - the values of the object are cached and ready to be retrieved. Here's the rub, you can only get to them by sess.LOAD, sess.GET or navigation to the object, that means you must know it's ID or use a fetch= 'select' strategy instead of "join" in your mapping relations. If you cache collections, then just the ID's are cached in the collection for that parent object. You'd need to specify the child's class to be cachable too <cache...>.
3) setup your session to use the 2nd level cache with session.setCacheMode(CacheMode.Normal) - ie, read and write to cache through your session.
4) Query cache works hand-in-hand with the 2nd level cache, in other words, if you issue a Query like Query q=sess.createQuery("from category"), and you setup the query to be cacheable, with q.setCacheable(true), then your query will be cached - if you issue the >>same<< query again, it won't hit the database even on new sessions... This is ideal for read-only data (like reference data) that doesn't ever change.

I hope that helps to get a fundamental understanding of it, and get you on your way...

_________________
-JT

If you find my replies helpful, please rate by clicking 'Y' on them. I appreciate it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 8:18 am 
Newbie

Joined: Thu Mar 30, 2006 2:10 pm
Posts: 14
jt_1000 wrote:
here is the quick cliff-notes to 2nd level cache...

1) you must setup a cache-provider in your hibernate.properties - choose ehCache.
2) you must specify what you want to cache - The two things that you can cache directly in the 2nd level are: Objects and Collections - if you cache objects, then basically it is an index by it's ID (either by <id> tag or by the hashCode method on your java class, if provided) into a table of objects - the values of the object are cached and ready to be retrieved. Here's the rub, you can only get to them by sess.LOAD, sess.GET or navigation to the object, that means you must know it's ID or use a fetch= 'select' strategy instead of "join" in your mapping relations. If you cache collections, then just the ID's are cached in the collection for that parent object. You'd need to specify the child's class to be cachable too <cache...>.
3) setup your session to use the 2nd level cache with session.setCacheMode(CacheMode.Normal) - ie, read and write to cache through your session.
4) Query cache works hand-in-hand with the 2nd level cache, in other words, if you issue a Query like Query q=sess.createQuery("from category"), and you setup the query to be cacheable, with q.setCacheable(true), then your query will be cached - if you issue the >>same<< query again, it won't hit the database even on new sessions... This is ideal for read-only data (like reference data) that doesn't ever change.

I hope that helps to get a fundamental understanding of it, and get you on your way...


Wow jt_1000, thank you very much for the fundamental breakdown of the cache and how to implement.

Thanks for taking the time again!
Timothy Grant Vogelsang


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 10:17 am 
Contributor
Contributor

Joined: Thu May 12, 2005 8:45 am
Posts: 226
Please note that jt_1000's answer has lots of Java-specific items which might be a bit confusing.

For NHibernate 1.0.2, your choices are SysCache and PrevalenceCache. There's a commercial one out there too, but I forget what it is, and it's really expensive. If you want to try the code from SVN, there also a MemCache client - memcached is an in-memory service which listens on a socket, and the clients can do load balancing and failover.

The rest is mostly correct, but you need to replace Java syntax with .NET syntax where appropriate. See the NHibernate docs on the configuration syntax items like query caching and stuff.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 05, 2006 8:03 pm 
Expert
Expert

Joined: Mon Jan 09, 2006 5:01 pm
Posts: 311
Location: Sacramento, CA
sorry about that - I hope it wasn't misleading in any sense - sometimes I simply do a search for "unanswered" questions and then reply w/o noticing the forum.... Glad it helped for NHibernate too.


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