我正在尝试让hibernate使用spring托管事务。无论我做什么,我总是得到“没有交易正在进行中”的例外。我唯一不明白的是:
如果我没有在我的sessionFactory.getCurrentSession()
方法中调用@Transactional
,一切正常,我可以看到HibernateTransactionManager
调用了事务生命周期方法 - doGetTransaction(...), doCommit(...)
等等。错误被抛出。
当我在方法中添加sessionFactory.getCurrentSession()
时,我仍然会看到doGetTransaction()
(很明显),但只要getCurrentSession()
被调用,我就会开始看到doRollback()
最后我得到'没有交易正在进行'的例外。我已经花了一整天时间,希望有人帮忙。尝试改变事务范围,xml配置,基本上我能想到的一切。使用最新的spring和hibernate版本(分别为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$$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)
答案 0 :(得分:2)
显然问题在于将Java DCEVM与HotswapAgent一起使用。当我从tomcat运行配置中删除-XXaltjvm=dcevm -javaagent:C:\hotswap-agent.jar
时,一切都按预期工作。我想这是使用“hacky”软件的副作用之一。我对这些事情的了解太小,甚至无法猜测实际问题是什么。