Friday, 29 February 2008

Hibernate is Lazy : The LazyInitializationException scenario

While Lazy Instantiation is an important feature and does improve performance in J2EE applications, it can be a bit of a headache if not correctly used or should I say implemented.

Consider a J2EE scenario where you might have a one-to-many parent-child relationship defined between two classes.In the scenario, data retrieval is handled by the DAO layer. In it a DAO retrieves a dataset and passes it to a view. The view is controller by a servlet and rendered by a JSP. The JSP attempts to print out the parent's name and voila, you have a LazyInitializationException.

As section 19.1.4 of the Hibernate documentation states " A LazyInitializationException will be thrown by Hibernate if an uninitialized collection or proxy is accessed outside of the scope of the Session, ie. when the entity owning the collection or having the reference to the proxy is in the detached state."

Two obvious (and suggested) counter strategies would be
1. Keep the session open until all objects that are required have been initialised.

In my opinion, this is not a good approach as you are liable to forget closing a session and will end up nesting transactions. Something which the J2EE container does not like.
(Yes, Yes..you can use a servlet filter to ensure that you do close the session but you can have performance degradation with requests being parsed by the filter. In addition to this, you will also need to have a robust exception handling mechanism in place to ensure that sessions do get closed when exceptions occur.

2. Prepare all uninitialized collections in the business layer before they get passed to the view.
I feel that this is a better and a much more organised strategy as you can initialise the objects and their associated objects in the same DAO call (and the same session).
Of course you need to be sure that you are going to really use these objects otherwise you will end up with a lot of unused objects on the heap and a sluggish application to boot.

While there are several strategies to counter the LazyInitializationException scenario, To fully understand the solution, one should have a good grasp of the Fetching strategies employed by Hibernate as they are the key to the problem and to the solution.