Hi Guys! I am back with a new Post titled “Dealing with LazyInitializationException”. In Hibernate “lazy initialization” is one of the key feature of Hibernate which allows it to lazily initialize associated properties of an object. For example, if you are interacting with Order object, which has relationship with Item object like one order can have multiple items, and if the fetching strategy for Item property is “Lazy” then Hibernate will not initialize the Item collection which holds all items at the time it initialized Order object.

If we close the hibernate session and try to access an attribute from Item object, we will get “org.hibernate.LazyInitializationException: could not initialize proxy – no Session in Hibernate”.The reason of the error is that the hibernate needs to go database to initialize the proxy object, and connection is already closed. Proxy object is only initialized in Hibernate if you access any attribute other than id itself, that’s why you would only see LazyInitializationException if you try to access an attribute other than id. In this blogpost, I will explain various ways to deal with this common exception.

1) Trying to access a lazy property after a session is closed

This is the most common reason of “LazyInitializationException: could not initialize proxy”. Here is one example:-

Session sess = factory.openSession();
Transaction tx = sess.beginTransaction();

Order order = (Order) s.createQuery("from Order o where o.id=:id").setString("id", "451").uniqueResult();
.....
...........
................
tx.commit();
sess.close();

List<Item> items = order.getItems(); //  This line will throw an exception

sess: Session is obtained from Session Factory and is used to interact with the database like save, retrieve etc. It is a bridge between object and table.

In the above example we open a session, begin the transaction and retrieve some data from the database. After closing the session we try to access item collection which throws the LazyInitializationException because the order object is in detached state.

Solution 1:-

The most easy solution would be to change the fetch strategy for Item collection to “EAGER” but it is not a good practice. Suppose, we have 100-200 items associated with each order. When we initialize the order object then hibernate would automatically load the associated items collection with order even if we don’t require it. It consumes space and require more time while querying.

Solution 2:-

When I faced this exception in my project I tried this solution which worked. In the above example we can simply touch/access one object so that the items collection is available even after the session is closed and the object goes into detached state. We can use the code below before a session is closed.

............
................
List<Item> items = order.getItems();
if(items.size()>0) {
items.get(0);
}
.........
...............
tx.commit();
sess.close();

You must be wondering that why

order.getItems();

is not enough to load the items collection. It is because the getCollection() method does not actually load the collection for use. To actually load the collection we need to touch/access atleast one object from the items list.

That was all about LazyInitializationException.
Thanks 🙂