I'm trying to get hibernate working with spring managed transactions. No matter what I do I always get 'no transaction is in progress' exception. The only thing I don't understand is this:
If I don't call sessionFactory.getCurrentSession()
in my @Transactional
method, everything goes fine and I can see HibernateTransactionManager
transaction lifecycle methods being called - doGetTransaction(...), doCommit(...)
etc. and no error is thrown.
When I add sessionFactory.getCurrentSession()
in my method I still see doGetTransaction()
(obviously), but as soon as getCurrentSession()
is called I'm starting to see doRollback()
and in the end I'm getting 'no transaction is in progress' exception. I've already spent whole day on it, hope someone helps. Tried changing transaction scope, xml configuration, basically everything I can think of. Using latest spring and hibernate versions (4.3.3 and 5.2.3 respectively)
applicationContext.xml:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/trainings"/>
<property name="password" value="xxx"/>
<property name="username" value="xxx"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager" >
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource" />
</bean>
<context:annotation-config/>
<context:component-scan base-package="webtrainings.beans"/>
<tx:annotation-driven transaction-manager="transactionManager" />
GenericDAO.java:
@Repository("genericDao")
@Scope(value = "singleton")
public class GenericDAO<T> {
@Autowired
private SessionFactory sessionFactory;
@Autowired
private ApplicationContext appContext;
public void getAll(Class<T> clazz) {
factory.getCurrentSession();
}
}
MyService.java:
@Service("myService")
@Transactional
public class MyService {
@Autowired
GenericDAO genericDAO;
@Transactional
public void hehe() {
genericDAO.getAll(Training.class);
}
}
HelloController.java:
@Controller
@RequestMapping(value = "/welcome")
public class HelloController {
@Autowired
MyService myService;
@Autowired
ApplicationContext applicationContext;
@RequestMapping(method = RequestMethod.GET)
public ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("hello");
model.addObject("msg", "hello world");
myService.hehe();
return model;
}
}
spring-servlet.xml (mvc):
<context:component-scan base-package="webtrainings.utils"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Stacktrace:
javax.persistence.TransactionRequiredException: no transaction is in progress
org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3430)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1397)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1393)
org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:487)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
webtrainings.beans.MyService$$EnhancerBySpringCGLIB$$3fca725c.hehe(<generated>)
webtrainings.utils.HelloController.handleRequestInternal(HelloController.java:32)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:180)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Apparently the problem is in using Java DCEVM with HotswapAgent. When I remove -XXaltjvm=dcevm -javaagent:C:\hotswap-agent.jar
from tomcat run configuration everything works as expected. I guess this is one of the side effects of using "hacky" software. My knowledge in these things is too small to even try to guess what the actual problem is.