LazyInitializationException in JPA and Hibernate LazyInitializationException in JPA and Hibernate spring spring

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.


The best way to solve this would be to first understand why and when the session is closed inspite of being under single transaction. And the best way for that would be to enable the hibernate (as you are using hibernate as JPA provider) logging level to DEBUG in log4j configuration and track where the sessions are closed. This would give you a clear picture. Although the stack trace suggests that the underlying session was closed but there are obviously no reason why ? You can post the relevant debug/info messages logged.

Also you can set up logging for spring framework to track the transaction management infrastructure

The logs give fairly good messages on when the underlying session was closed and transaction committed.

For e.g.,

opened session at timestamp: 13476520251.......................after transaction begin..............select x,y,z from........................commit............flushing session..after transaction completion..closing session


I also got this problem, but inspired by your answer, I solve it. Here is it.

My application try to use Jpa Repository to handle the data in a rest controller, which turns out got the no session error. Here is the code:

@RequestMapping(value = "/create", method = POST, consumes = MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<Void> create(@RequestBody Map<String, Object> params) {    Project project = Factory.project().build(params);    project = repository.save(project);    return ResponseEntity.ok().build();}

According to this post and this post, we know that beans in servlet context can reference beans in the application context. So the TransactionManager can not access to this rest controller bean, resulting this error.

Solution, creating a middle layer bean application context between rest controller and repository, encapsulating those code. I try it, it works fine. Update the code later.