How to Solve the Lazyinitializationexception When Using JPA and Hibernate

How to fix org.hibernate.LazyInitializationException - could not initialize proxy - no Session

What is wrong here is that your session management configuration is set to close session when you commit transaction. Check if you have something like:

<property name="current_session_context_class">thread</property>

in your configuration.

In order to overcome this problem you could change the configuration of session factory or open another session and only than ask for those lazy loaded objects. But what I would suggest here is to initialize this lazy collection in getModelByModelGroup itself and call:

Hibernate.initialize(subProcessModel.getElement());

when you are still in active session.

And one last thing. A friendly advice. You have something like this in your method:

for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}

Please insted of this code just filter those models with type id equal to 3 in the query statement just couple of lines above.

Some more reading:

session factory configuration

problem with closed session

How to solve the “failed to lazily initialize a collection of role” Hibernate exception

If you know that you'll want to see all Comments every time you retrieve a Topic then change your field mapping for comments to:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "topic", cascade = CascadeType.ALL)
private Collection<Comment> comments = new LinkedHashSet<Comment>();

Collections are lazy-loaded by default, take a look at this if you want to know more.

Hibernate LazyInitializationException using Spring CrudRepository

So you can do it by initializing businessCategoruSet in Service so instead of using @Transactional in Repository use it in Service.
Let write some method like get business by id or list of business in repository and access that method from service.

@Transactional
public Class BusinessService{

@resource
BusinessRepository businessRepository;

public Business getBusiness(){
Business business = businessRepository.getBusiness();
//Here you should initialize BusinessCategorySet
Object object = business.getBusinessCategoriesSet().size();
}
}

For more details about @Transactional Refer this link

LazyInitializationException in JPA and Hibernate

Thanks to Shailendra I started to look closely at the transaction and noticed that the transaction was never starting. With that information I did some investigation and found this: Spring @Transaction not starting transactions. I put <tx:annotation-driven/> in my servlet-context.xml file and suddenly the transaction for logDOI started up and everything worked correctly; I no longer got the LazyInitializationException. I am not at all clear as to why that worked. Any information on that would be appreciated.

Update:

I figured it out. A critical piece of my problem was in the servlet-context.xml file. This is what it looked like

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>

<context:component-scan base-package="org.myapp.doi" />

</beans:beans>

The major problem was in that context:component-scan line. Spring MVC creates two context which beans are instantiated in: the root application context defined with the contextConfigLocation parameter in the web.xml file and the servlet context defined in the DispatcherServlet in the web.xml file. The servlet context could see the application context but not the other way around. Now, as a result of context:component-scan being defined in the servlet context and scanning the entire application namespace, my DAO was being instantiated in the servlet context. However, the transaction annotation scanning was being done in the application context and the AOP proxy stuff for it could not be done from there. Simply modifying the context:component-scan in the servlet context to scan only the MVC controllers (<context:component-scan base-package="org.myapp.doi.web" /> fixed everything; the DAO was being created in the application context and properly setup for transactions.

Hibernate Lazy Initialization Exception for loading lazy list

I’m going to start by assuming you want your collection to be lazy loaded.

Hibernate’s session can be closed in a lot of contexts, and once the session is closed, it won’t be able to fetch any lazy loaded collections.

Generally Hibernate is very good at keeping sessions open for the lifecycle of HTTP threads in a web app context (Spring’s “open session in view”). Reasons the session could be closed include that the object was handed off from one thread to another, or the object was cached and then accessed by another thread.

But it can be more difficult if your code is running in a job or a non-web application context.

Fixes

1. Create a repository method to explicitly fetch the collection

Using @Query and join fetch, add a repository method that explicitly eager-loads the collection.

2. Call .toString() on the collection after fetching the object.

This is a nasty hack that I’ve seen many people use in the real world before. Basically, before caching the object or handing it off to an executor or somewhere where it would be accessed by another thread, call .toString() on the collection to load it. Usually leave a comment explaining why.

3. Add @Transactional to a method that is both fetching the data and accessing the collection

This has many implications other than keeping the session alive (e.g. database operations succeed and fail together), but can be a quick fix to keep the session alive in for example a job method.

Hope this helps.



Related Topics



Leave a reply



Submit