views:

528

answers:

5

I want to manage a Transaction in my persistence layer, But when I try to fetch the results lazily I get this error:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

Can I use LockMode or any other way to solve this problem? Can a find a Object by its id without any Transaction?

+1  A: 

Your problem is that the Hibernate session is already closed when you try to access the content. Hibernate cannot load the content without a session. There are usually two ways to mitigate this problem:

  1. Don't close the session until you are done with the page. This pattern is called "session in view" and can for example be implemented with a servlet filter.

  2. Initialize all contents that you'll need before closing the session. If you want to initialize the whole object you can use Hibernate.initialize(object).

edit: You cannot do anything outside of an transaction in Hibernate.

Thanks. I knnow that tis proble is becaue the owing session is closed. Can you provide more information on second solution that you have provided.
A: 

Typically the problem is that one of the attributes of the object is lazily loaded. One thing you can do is to have it pre-loaded in your query:

from Sale sale where sale.date > :startDate left join fetch sale.product

This will pre-fetch the sale.product object.

this site has more information: http://www.javalobby.org/articles/hibernate-query-101/.

-Dave

Dave
+2  A: 

You can also look at the official solution from hibernate at http://www.hibernate.org/43.html

kazanaki
A: 

There are many ways to pre-fetch properties, so they are there after session is closed:

  1. Just call appropriate getter. After field is fetched into bean it is there after session is closed.
  2. Use appropriate attribute in bean descriptor in JPA you'd use @OneToMany(fetch = FetchType.EAGER), but there are similar hibernate ways to do it.
  3. You may initialize field in HQL query (I'm not sure if it works in HQL, but i think it does), look for FETCH INTO keyword.
jb
A: 

Or just use another ORM ... like Ebean ORM where lazy loading just works :)

Rob