3

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: pojo.Person.address, no session or session was closed.

I am getting this exception and I'm using Spring 3.0 and Hibernate 3.6.

2
  • 5
    Unfortunately, no one can help you unless you prepare a small and concise example reproducing the same error and post it here. Commented Nov 28, 2011 at 7:55
  • additionally hibernate by default load collection in lazy way means it will not load the collection and will return proxies object and you might be trying to access the collection after the session is closed. Commented Nov 28, 2011 at 8:57

3 Answers 3

8

It looks like you have an Entity called Person which has a lazily loaded mapped collection of Addresses? You have loaded the Person and the session it was loaded in has now been closed.

After the session was closed you then attempted to access that collection of address and Hibernate attempted to load them. However, that is not possible if the original session is no longer available.

In order to access the address property you have a few options:

  1. Use the OpenSessionInView pattern to ensure that the Hibernate session is held open for the duration of the request/response cycle (Since you've tagged Spring MVC I'll assume this is a web based operation). This essentially scopes your Hibernate session to the HTTP request.

  2. Ensure that all required properties are loaded before the session is closed (transaction committed). You can do this using

    Hibernate.initialize(person.address)

or by writing HQL that uses a left join fetch. This could be something like:

createQuery("from Person as person left join fetch person.address")

This will override any lazy loading configuration for this query only and ensure that any collections are initialized.

Sign up to request clarification or add additional context in comments.

3 Comments

Alex, Don't you think that is equivalent to FetchType.EAGER? And which will degrade the performance.
But you need to fetch this eagerly, otherwise you get LazyInitializationExceptions!! Which is exactly what you've seen! You WILL need to load this collection so you might as well do it before you close your session. The beauty of using a left join fetch is that you can specify FetchType.Lazy in your mappings. This will be used most of the time when you know you won't need to access the address collection. But when you know you will need to access the collection you can override the lazy mapping! Do you get it?
The exception you're seeing indicates that you've tried to access the address property. Therefore you're going to have to load it at some point. It's not going to magically appear in your session with no performance overhead. As nice as that would be.
3

Most probably, you don't have transaction management set up. That is, Spring uses default transaction scope, which is transaction per HibernateTemplate call, and closes session right after return from HibernateTemplate.

You can do one of three things:

  1. set up transactions,
  2. switch to explicit session handling,
  3. use Criteria API or fetch join in order to prefetch the details you need.

2 Comments

Thanx alf for quick reply. can you explain third option? i.e. using criteria api or fetch join. Actually I'm having existing project which contains pojos with hbm.xml and it is to be converted into pojos with annotations.
0

I was seeing this issue because I had failed to annotate a method in a service with @Transactional. It seems that Hibernate closes the session when a call to another method is made (even within the same class) unless the caller is annotated appropriately.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.