我有一个使用Hibernate 4和Spring Transactions的Spring 3.2应用程序。所有方法都运行良好,我可以正确访问数据库以保存或检索实体。然后,我引入了一些多线程,并且由于每个线程都在访问db,所以我从Hibernate中收到以下错误:
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
我从网上读到我必须添加<prop key="hibernate.current_session_context_class">thread</prop>到Hibernate配置中的内容,但是现在每次我尝试访问数据库时,都会得到:
<prop key="hibernate.current_session_context_class">thread</prop>
org.hibernate.HibernateException: saveOrUpdate is not valid without active transaction
但是,我的服务方法带有注释@Transactional,并且在添加之前一切工作正常<prop key="hibernate.current_session_context_class">thread</prop>。
@Transactional
尽管方法带有@Transactional注释,但为什么没有事务?我怎么解决这个问题?
这是我的Hibernate配置(包括会话上下文属性):
<?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和spring管理的事务时, 除非* 您正在使用JTA, 否则 切勿 乱用hibernate.current_session_context_class属性。 *
hibernate.current_session_context_class
默认情况下,Spring将设置自己的CurrentSessionContext实现(SpringSessionContext),但是如果您自行设置,则情况并非如此。基本上破坏了适当的交易集成。
CurrentSessionContext
更改此设置的唯一原因是,每当您要使用JTA管理的事务时,都必须进行设置以与JTA正确集成。