Failed to lazily initialize a collection of role could not initialize proxy – no Session

In this post, We will see about Failed to lazily initialize a collection of role could not initialize proxy – no Session hibernate exception.

Understanding the reason for this exception.

Generally, This exception comes when two entities are in association mapping with fetch= FetchType.LAZY (for eg. OneToMany relationship) and we try to get child entity from the parent entity after session gets closed.

For example, consider we have two entities in OneToMany relation as below.

Story.java

 

Below code will throw failed to lazily initialize a collection of role could not initialize proxy – no Session hibernate exception.

Note – In the above code snippet, I have intentionally closed the session to replicate the issue.

{
“timestamp”: “2020-04-29T10:24:58.705+0000”,
“status”: 500,
“error”: “Internal Server Error”,
“message”: “Could not write JSON: failed to lazily initialize a collection of role: com.hibernatejpa.entity.Book.storyList, could not initialize proxy – no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.hibernatejpa.entity.Book.storyList, could not initialize proxy – no Session (through reference chain: com.hibernatejpa.entity.Book[\”storyList\”])”,
“path”: “/book/1”
}

Code snippet which is responsible for this exception.

 

Observe the above code, if the session is null then throwLazyInitializationException() method will get called. Let’s have a quick look into throwLazyInitializationException().

This is from where we are getting this exception.

Fixing by using @Transaction annotation.

The easy and quick fix would be just used @Transactinal annotation with your method.

We are using @Transactinal with findByBookId() method and yes now even we are doing session.close() we should don’t have LazyInitializationException.

Fixing by calling child entity in a separate method before the session is closed.

If you don’t want to use @Transactinal annotation, we can define a separate method where we can call child entity. B

In the above code, we are calling getStory() method just before closing the session.

 

Fixing by defining enable_lazy_load_no_trans=true in application.properties file.

In application.properties file we can define enable_lazy_load_no_trans = true.
We need to define spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true in applcation.properties file. By defining this attribute we are telling to hibernate initialize lazy state even for outside transactions. It will create a new temporary session and we will able to do book.getStoryList() without any LazyInitializationException.
just recall the code snippet from where we were getting this exception.

 

If we use enable_lazy_load_no_trans=true the value of allowLoadOutsideTransaction would be true and openTemporarySessionForLoading() will create temperary session.

 

Fixing by fetch= FetchType.EAGER.

Fetch child entity eagerly then it will available even after the session will get close.

 

 

An example using Hibernate/JPA and Spring Boot from scratch.

Let’s see an example of Failed to lazily initialize a collection of role could not initialize proxy – no Session in Hibernate.

Create a maven project with the name lazilyinitializeexception and modify the pom.xml with the below code.

Note – In pom.xml we have defined javac.exe path in configuration tag. You need to change accordingly i.e where you have installed JDK.

If you see any error for oracle dependency then follow these steps.

Book.java

Story.java

 

Define the repository interface extending CrudRepository.

BookRepository.java

Define service interface i.e BookService.java

Define service implementation class.

BookServiceImpl.java

Note – See here more about @Component, @Controller, @Service and @Repository annotations here.

Define the controller class or endpoint.

BookController.java

Note – See more details about @Controller and RestController here.

Define the JpaConfig.java

Step 12 – Define the SpringMain.java

 

And finally, we have an application.properties file where we have database details.

application.properties

We are almost done. Just build the project once running the main method. Open git bash or cmd and Run mvn clean install.

Let’s deploy the application running SpringMain class as a java application and do testing. First, we will save one book with three stories.

 

Sample request JSON data-

 

Failed to lazily initialize a collection of role could not initialize proxy - no Session

 

In case the session is closed.

Using @Transaction or other solutions.

The database query generation for all Scenario.

 

The query generated for the first three solutions.

Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_name2_0_0_ from book book0_ where book0_.book_id=?

Hibernate: select storylist0_.book_id as book_id3_1_0_, storylist0_.story_id as story_id1_1_0_, storylist0_.story_id as story_id1_1_1_, storylist0_.story_name as story_name2_1_1_ from story storylist0_ where storylist0_.book_id=?

The query generated for the fourth solution(fetch= FetchType.EAGER).
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_name2_0_0_, storylist1_.book_id as book_id3_1_1_, storylist1_.story_id as story_id1_1_1_, storylist1_.story_id as story_id1_1_2_, storylist1_.story_name as story_name2_1_2_ from book book0_ left outer join story storylist1_ on book0_.book_id=storylist1_.book_id where book0_.book_id=?

That’s all about Failed to lazily initialize a collection of role could not initialize proxy – no Session

Visit docs related to LazyInitializationException.

You may like.

Summary – We can fix failed to lazily initialize a collection of role could not initialize proxy – no Session using @Transactinal, defining a separate method to call child entity, enable_lazy_load_no_trans=true and fetch= FetchType.EAGER. You can choose any way according to your need.

Top