本文介绍了Spring事务和hibernate.current_session_context_class的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  org.hibernate.HibernateException:非法尝试将一个集合与两个打开的会话相关联

我必须在我的Hibernate配置中添加< prop key =hibernate.current_session_context_class>线程< / prop> ,但现在每次尝试访问我得到的数据库:

  org.hibernate.HibernateException:如果没有活动事务,saveOrUpdate无效

但是我的服务方法用 @Transactional 注释,并且所有工作都正常在添加< prop key =hibernate.current_session_context_class>线程< / prop>



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



这是我的Hibernate配置(包括会话上下文属性):

 <?xml version =1.0encoding =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/弹簧-TX-3.1.xsd>

< bean
id =sessionFactory
class =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSource>
< ref bean =dataSource/>
< / property>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.hbm2ddl.auto>建立< / 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>
< /道具>
< / property>
< property name =annotatedClasses>
< list>
...
< / list>
< / property>
< / bean>

< bean id =transactionManagerclass =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>

< tx:注解驱动的事务管理器=transactionManager/>


解决方案

使用spring和spring管理的事务永不 混淆了 hibernate.current_session_context_class 属性 UNLESS 使用JTA。 Spring将默认设置它自己的 CurrentSessionContext 实现(),但是如果你自己设置它,这不会是案件。基本上打破了正确的交易整合。

更改此设置的唯一原因是每当您想使用JTA托管事务时,您都必须设置此项以正确集成JTA。

I have a Spring 3.2 application that uses Hibernate 4 and Spring Transactions. All the methods were working great and I could access correctly the database to save or retrieve entities.Then, I introduced some multithreading, and since each thread was accessing to db I was getting the following error from Hibernate:

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

I read from the web that I've to add <prop key="hibernate.current_session_context_class">thread</prop> to my Hibernate configuration, but now every time I try to access the db I get:

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

However my service methods are annotated with @Transactional, and all was working fine before the add of <prop key="hibernate.current_session_context_class">thread</prop>.

Why there is no transaction although the methods are annotated with @Transactional? How can I solve this problem?

Here is my Hibernate configuration (including the session context property):

<?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"/>
解决方案

When using spring and spring managed transactions never mess around with the hibernate.current_session_context_class property UNLESS you are using JTA.

Spring will by default set its own CurrentSessionContext implementation (the SpringSessionContext), however if you set it yourself this will not be the case. Basically breaking proper transaction integration.

The only reason for changing this setting is whenever you want to use JTA managed transactions, then you have to setup this to properly integrate with JTA.

这篇关于Spring事务和hibernate.current_session_context_class的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 06:58
查看更多