LazyInitializationException in servlet
Posted by davidnewcomb on 29 Nov 2008 in Techie
Problem: Web traffic is coming through Tomcat to one of your servlets. Your servlet accesses a couple of hibernate objects but when it tries to load a lazy proxy you get:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: uk.co.bigsoft.proj.bus.Clip.aaf, no session or session was closed org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372) org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119) org.hibernate.collection.PersistentSet.size(PersistentSet.java:162) uk.co.bigsoft.proj.web.MyController.handleRequest(MyController.java:57) org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:808) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:431) javax.servlet.http.HttpServlet.service(HttpServlet.java:617) javax.servlet.http.HttpServlet.service(HttpServlet.java:717)We want something that can set up the transaction after calling
SimpleControllerHandlerAdapter.handle
and before calling our handleRequest
method and then commit or rollback the session depending on whether our controller throws an exception or not.
There appeared to be 2 choices to use:
OpenSessionInViewFilter
orOpenSessionInViewInterceptor
,
OpenSessionInViewInterceptor
is an interceptor which can be used to wrap any kind of technology, whereas the OpenSessionInViewFilter
is an Interceptor that can only be used in the web servlet environment.
Therefor you can use an interceptor in all cases but you can only use a filter in the web servlet case.
I found a clue in 13.4.3. Intercepting requests - the HandlerInterceptor interface of the reference manual. There is almost no reference to the OpenSessionInViewFilter
, so I think this is being obsoleted where as the OpenSessionInViewInterceptor
is covered in a whole section about interceptors (as a technology).
Interceptors just plug into the org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
in your bean definition configuration.
<bean
id="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"
>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean
id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
>
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">
<props>
<prop key="/getmy.html">myController</prop>
</props>
</property>
</bean>
And it all just worked.
Or if you are using annotations you could just wrap handleRequest
in @Transactional…!
There are pros and cons to annotating the transactions and using an interceptor, and when I find out what they are I’ll update this blog!2 comments
Comment from: Andrew Swan [Visitor]
splingo ;p
Form is loading...
It’s a bad idea for your client (e.g. the web layer) to be concerned with transactions; this is the job of the service layer. In other words, you should never mark your controllers with @Transactional, just in case you weren’t joking…