Hi,
I'm getting a very odd issue with transaction management when using a ContextLoaderListener. Any help would be much appreciated.
We have been using Transactions in our Spring MVC app for a couple of months now.
We put our contextConfigLocation definition right in the DispatcherServlet, and everything was working fine.
Here is our original, working web.xml:
And our daoContext.xml had:Code:<servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:servicesContext.xml classpath:databaseContext.xml classpath:daoContext.xml /WEB-INF/spring-servlet.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Now a couple of weeks ago, I had to integrate some other things, and the first step I needed to do was move the context instantiation to be in the ContextLoaderListener. All I changed was our web.xml to be:Code:<tx:annotation-driven transaction-manager="transactionManager" /> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
Now it seems that Transactions are being lost after exiting the service layer, since Hibernate is throwing LazyInitilization errors, complaining about not finding an open session. This is code that works fine with the original web.xmlCode:<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spring-servlet.xml /WEB-INF/spring-security.xml classpath:servicesContext.xml classpath:databaseContext.xml classpath:daoContext.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet>
Other than the Transactions, everything is working fine. All the beans are wired properly, data access is working properly, and our transactions are still open until we leave the service layer.
I've ran through some tests, and here is an over-simplification of what seems to be happening. All of the below are defined with the Transactional annotation
com.foo.bar.controller.mySpringController.handleRe quest()
com.foo.bar.service.impl.myServiceImpl.findBaz()
com.foo.bar.dao.impl.myDaoImpl.getBaz()
getBaz() is called just fine, returns as expected
findBaz() works just fine, lazy initialization works just fine, the entire object can be walked without issues
handleRequest() blows up with a lazy initialization error and can't find the session
And NOW for the REALLY annoying part. I have, kind of, gotten around the issue, however, I really dislike my solution. While playing around with some of my XML files, I moved the <tx:annotation-driven> and my transactionManager bean from the daoContext.xmlto the spring-servlet.xml context file, and EVERYTHING works when using the ContextLoaderListener
We can't use this solution because we're packaging our our service/data access layer (including context files, etc.) to use in several of our applications
Does the context load differently when instantiating it in a ContextLoaderListener rather than a DispatcherServlet?
Why would the transactional stuff work when I move it to a different context file when everything else in that context file works fine?
I can explain more if anybody can help me.
Thanks,
Scott.


Reply With Quote
