Monday, August 2, 2021

Dealing with org.hibernate.LazyInitializationException: could not initialize proxy - no Session in Hibernate Java

If you are working in the Hibernate framework, then you know that one of the key features of Hibernate is "lazy initialization", which allows the framework to lazily initialize dependencies, relationships, or associations lazily from the database on a need basis. For example, if you are dealing with a User object, which has a relationship with a Permission object like one user can have multiple permissions, then Hibernate may choose not to initialize the collection which holds all permissions at the time it initialized User object and instead returns a proxy object.


At this point, if you close your session and the letter tries to access an attribute from the Permission object, you will get "org.hibernate.LazyInitializationException: could not initialize proxy - no Session in Hibernate".

Why this error comes, because hibernate needs to go database to initialize the proxy object, and the connection is already closed. If you remember, what we discussed in the difference between get vs load in hibernate is that the Proxy object is only initialized in Hibernate if you access an 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 article, we will see different scenarios on which you could possibly get "org.hibernate.LazyInitializationException: could not initialize proxy - no Session in Hibernate" and how to solve them appropriately.

I have tried to explain the reasons which caused the error and explained the solution as to why it will work, but if you still face issues, then feel free to post it here.

By the way, a good understanding of lazy initialization is also a good Hibernate interview question, so this not only helps you to solve this error but also to do well during interviews.

And, if you are serious about improving your Hibernate and JPA skills then I also recommend you checking out these best Hibernate and JPA online courses. In this list, I have shared the best online courses to learn Hibernate and JPA for beginners and experienced developers. 





1) Code tries to access a lazy initialized property or collection and the session is not available.

This is by far the most common reason of "LazyInitializationException: could not initialize proxy". In order to find the reason you need to look your code carefully. Here is one example to understand, how lazy initialization exception comes in Hibernate :

Session s = sessions.openSession();
Transaction tx = s.beginTransaction();

Employee e = (Employee) s.createQuery("from Employee e where e.name=:empName")
                         .setString("empName", eName).uniqueResult();
List roles = u.getRoles();

tx.commit();
s.close();

String role = roles.get(0); //  This line will throw error

Exception in thread "main" org.hibernate.LazyInitializationException: 
    could not initialize proxy - no Session
   at org.hibernate.proxy.AbstractLazyInitializer.initialize
      (AbstractLazyInitializer.java:57)
   at org.hibernate.proxy.AbstractLazyInitializer.getImplementation
      (AbstractLazyInitializer.java:111)
   at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke
      (CGLIBLazyInitializer.java:150)

Easy Solution
Use lazy=false in hibernate mapping file.



Advantage and Disadvantages of lazy=false in Hibernate

org.hibernate.LazyInitializationException: could not initialize proxy - no Session in Hibernate JavaWell, one clear advantage is that it's easy to apply, all you only need to change in Hibernate configuration files e.g. Employee.hbm.xml. It also guarantees that the object will be fully initialized.

On the other hand, the main disadvantage of this approach can be slow performance. Since dependent objects are loaded at the time of persistent object loading, it will increase loading time.

Also since now, the object is fully initialized, their memory consumption would be very high. This can become more severe if your Collection classes are a big list of other objects, which are not always accessed.

Better Solution :

The real problem is that you are trying to access a collection in an object that is detached or the associated session is closed. You need to re-attach the object before accessing the collection to the current session. You can either reattach the object by calling the session.update(object); Or you can move the code which accesses proxy object to the line before you close the session.

In short, though making lazy=false is a simple and sure short way to solve "Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session" it is not a good solution because you are throwing away the Lazy Initialization feature of hibernating.

When lazy=false, the collection is loaded in memory at the same time that the object is requested. This means that if we have a collection with 1000 items, they all will be loaded in memory, despite we are going to access them or not. This can result in more memory consumption and slow initialization of objects with a lot of association or dependency.


2) Upgrading from Hibernate 2.1 to Hibernate 3.0

Cause: Hibernate 3.0 provide lazy loading default as true i.e. lazy ="true"
Solution: In hibernate mapping file set lazy= "false"

Context: You may see "org.hibernate.LazyInitializationException: could not initialize proxy - no Session" while upgrading from hibernate 2.1 to hibernate 3.0. You will suddenly find yourself puzzling what happened, it was working before the update. The reason is, Hibernate 3 introduced lazy loading as the default i.e. lazy="true". If you want it to work the same as before you can mark everything as lazy="false". Alternatively, you'll have to start eagerly initializing your entities and associations.


3) Hibernate with JPA Annotation

If you are using hibernate with JPA annotations and manually managing your transactions, then you can also try this as well to deal with LazyInitializationException in Hibernate . In your service class there should be a setter for entity manager with @PersistenceContext. change this to @PersistenceContext(type = PersistenceContextType.EXTENDED)

Then you can access lazy property in any where. By the way, its worth remember that, Spring EXTENDED persistence context type is for long conversation pattern, not the session-per-request pattern.

Hibernate interview questions with answers

4) Application wide Solution

There are situation, when we want an easy solution and doesn't care anything about performance e.g. for testing or prototyping purpose. In that case you can make following configuration change into your application to avoid this error, but remember the impact eager initialization can cause if this code makes its way to production.

if you are using XML configuration: add default-lazy="false" to your element
if you are using annotation configuration: add @Proxy(lazy=false) to all your entity classes.

That's all about how to fix Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session. We have seen that this error mainly comes when you have closed the connection and trying to access the proxy object which is no fully initialized. Since Proxy object needs a connection, you can either reattach object to the session or carefully avoid writing such code, which access uninitialized Proxy object.

Another way to avoid LazyInitializationException is to disable lazy initialization feature of hibernate for your entity classes by using lazy="false" or disable it completely for your application by using default-lazy="false".

This solution is not recommended for production use due to performance reasons but can be used during prototyping, testing, and demo. Don't surprise if you first time sees this error when upgrading from Hibernate 2.1 to 3.0, because that's the version when Hibernate made lazy initialization enabled by default. 

If you have faced this error in any other scenario or trying to solve "org.hibernate.LazyInitializationException: could not initialize proxy - no Session", you can also post your error and code here and we can take a look together.


Other Hibernate Articles and Interview Questions you may like
  • Difference between First and Second level cache in Hibernate? (answer)
  • Difference between get() and load() method in Hibernate? (answer)
  • 5 Spring and Hibernate Training Courses for Java developers (list)
  • 2 Books to Learn Hibernate for Beginners (books)
  • 5 Books to Learn Spring Framework for Beginners (books)
  • Why Hibernate Entity class should not be final in Java? (answer)
  • 10 Hibernate Questions from Java Interviews (list)

Thanks for reading this article, if you like this article and the interview question then please share it with your friends and colleagues. If you have any questions or feedback then please drop a comment.

14 comments :

Kishore Dasari said...

2015-03-06 14:19:55,712 [TP-Processor20] DEBUG org.springframework.web.portlet.handler.SimpleMappingExceptionResolver - Resolving exception from handler [com.lexmark.cdm.portlet.PartyEnrichController@74eef9db]: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.lexmark.cdm.common.domain.ActiveLocation.activePartyRecordList, no session or session was closed
2015-03-06 14:19:55,713 [TP-Processor20] DEBUG org.springframework.web.portlet.handler.SimpleMappingExceptionResolver - Resolving to default view 'exception/defError' for exception of type [org.hibernate.LazyInitializationException]
2015-03-06 14:19:55,713 [TP-Processor20] DEBUG org.springframework.web.portlet.handler.SimpleMappingExceptionResolver - Exposing Exception as model attribute 'exception'
I want to resolve this issue asap, could anyone tell me what are the possible scenarious to resolve this exception. I'm using annotations for my bean classes.

Anonymous said...

I am using
@PersistenceContext(type= PersistenceContextType.EXTENDED)
public EntityManager entityManager; in my Spring4 Beans (Stateful) with Hibernate 3.
No LazyInitializationException throws.

Anonymous said...

I don't think that your first explanation is the best solution without some sample code. No offense, but it makes me more confusing: "You can either reattach the object by calling session.update(object);" How would you solve this "object" within your sample. And this statement also "Or you can move the code which access proxy object to the line before you close the session." is not really much helpful.

javin paul said...

@Anonymous, noted, will put some code there to make point more clear.

Sonam Gupta said...

I am getting lazyInitializationException while running my JUnit test case. I found a simple solution to change join fetch type from LAZY to EAGER but that can slow down performance, could you suggest any solution in case JUNIT Testing.

Keyur Bhanderi said...

Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session

javin paul said...

@Keyur, did you try solutions given here? It could be one of the reasons mentioned above.

Ferhad said...

Great Article...:)) I fixed my problem by third solution. i only add type = PersistenceContextType.EXTENDED parameter to @PersistenceContext and it works:)

Anonymous said...

Hi fellows. I am wondering if I can achieve a solution where that whenever a Hibernate entity is accessed outside a transaction, hibernate should not care about the object and it should act like a normal POJO, returning null.

Someone can help?

Anonymous said...

I am also getting lazy initialization error eventhough we tryied following things,
Set session object before calling Hibernate.initialize, Call Hibernate.initialize for all objects for which fetch type is lazy. We generated Hibernate pojo's using maven plugin. Hence we cant set any property in pojo level

Following are the errors.

[ERROR] 2016-08-24 16:47:29.230 [[chim-interchange-services-0.0.48].connector.VM.mule.default.receiver.07] LazyInitializationException - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.Hibernate.initialize(Hibernate.java:393) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]

Lire un fichier excel said...

i resolved this exception by changing lazy to eager thanks to this link
http://resolvedexceptions.blogspot.com/2016/08/orghibernatelazyinitializationexception.html

Unknown said...

Thank you so much .

It helps me alot as well as it gives me a better understanding.

Unknown said...

Thanks man, you're a hero!

Madhusudan Rai said...

Thanks Man

Post a Comment