Hibernate Spring 事务性没有正在进行的事务
Hibernate Spring Transactional no transaction is in progress
我正在尝试让休眠与 spring 托管事务一起工作。无论我做什么,我总是得到 'no transaction is in progress' 异常。我唯一不明白的是:
如果我不在 @Transactional
方法中调用 sessionFactory.getCurrentSession()
,一切正常,我可以看到 HibernateTransactionManager
事务生命周期方法被调用 - doGetTransaction(...), doCommit(...)
等。并且不会抛出任何错误。
当我在我的方法中添加 sessionFactory.getCurrentSession()
时,我仍然看到 doGetTransaction()
(很明显),但是一旦调用 getCurrentSession()
我就开始看到 doRollback()
最后我得到 'no transaction is in progress' 异常。我已经花了一整天的时间,希望有人能帮忙。尝试更改事务范围、xml 配置,基本上我能想到的一切。使用最新的 spring 和休眠版本(分别为 4.3.3 和 5.2.3)
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>
堆栈跟踪:
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$fca725c.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)
显然问题在于将 Java DCEVM 与 HotswapAgent 一起使用。当我从 tomcat 运行 配置中删除 -XXaltjvm=dcevm -javaagent:C:\hotswap-agent.jar
时,一切都按预期工作。我想这是使用 "hacky" 软件的副作用之一。我对这些事情的了解太少,甚至无法猜测实际问题是什么。
我正在尝试让休眠与 spring 托管事务一起工作。无论我做什么,我总是得到 'no transaction is in progress' 异常。我唯一不明白的是:
如果我不在 @Transactional
方法中调用 sessionFactory.getCurrentSession()
,一切正常,我可以看到 HibernateTransactionManager
事务生命周期方法被调用 - doGetTransaction(...), doCommit(...)
等。并且不会抛出任何错误。
当我在我的方法中添加 sessionFactory.getCurrentSession()
时,我仍然看到 doGetTransaction()
(很明显),但是一旦调用 getCurrentSession()
我就开始看到 doRollback()
最后我得到 'no transaction is in progress' 异常。我已经花了一整天的时间,希望有人能帮忙。尝试更改事务范围、xml 配置,基本上我能想到的一切。使用最新的 spring 和休眠版本(分别为 4.3.3 和 5.2.3)
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>
堆栈跟踪:
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$fca725c.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)
显然问题在于将 Java DCEVM 与 HotswapAgent 一起使用。当我从 tomcat 运行 配置中删除 -XXaltjvm=dcevm -javaagent:C:\hotswap-agent.jar
时,一切都按预期工作。我想这是使用 "hacky" 软件的副作用之一。我对这些事情的了解太少,甚至无法猜测实际问题是什么。