Spring事务和hibernate.current_session_context_class

我有一个使用Hibernate 4和Spring事务的Spring 3.2应用程序。 所有的方法工作得很好,我可以正确访问数据库来保存或检索实体。 然后,我介绍了一些multithreading,并且由于每个线程都访问数据库,我从Hibernate获得以下错误:

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 

我从网上读到,我必须添加<prop key="hibernate.current_session_context_class">thread</prop>到我的Hibernateconfiguration,但现在每次我尝试访问数据库我得到:

 org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction 

然而,我的服务方法是用@Transactional注释的,并且在添加<prop key="hibernate.current_session_context_class">thread</prop>之前,所有工作都正常。

为什么没有交易,虽然方法用@Transactional注释? 我该如何解决这个问题?

这里是我的Hibernateconfiguration(包括会话上下文属性):

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <!-- Hibernate session factory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" > <property name="dataSource" > <ref bean="dataSource" /> </property> <property name="hibernateProperties" > <props> <prop key="hibernate.hbm2ddl.auto">create</prop> <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.current_session_context_class">thread</prop> </props> </property> <property name="annotatedClasses" > <list> ... </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> 

当使用spring和springpipe理的事务时, 除非使用JTA, 否则 不要 混淆 hibernate.current_session_context_class属性。

Spring会默认设置它自己的CurrentSessionContext实现( SpringSessionContext ),但是如果你自己设置,情况就不会如此。 基本上打破了正确的交易整合。

更改此设置的唯一原因是只要您想使用JTA托pipe事务,那么您必须将其设置为与JTA正确集成。