Spring Транзакции и hibernate.current_session_context_class

У меня есть приложение Spring 3.2, которое использует Hibernate 4 и Spring Transactions. Все методы работали отлично, и я мог правильно получить доступ к базе данных для сохранения или извлечения объектов. Затем я ввел некоторую многопоточность, и, поскольку каждый поток обращался к базе данных, я получал следующую ошибку от Hibernate:

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

Я прочитал в Интернете, что мне нужно добавить <prop key="hibernate.current_session_context_class">thread</prop> в мою конфигурацию Hibernate, но теперь каждый раз, когда я пытаюсь получить доступ к базе данных, я получаю:

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

Однако мои методы обслуживания помечены @Transactional, и до добавления <prop key="hibernate.current_session_context_class">thread</prop> все работало нормально.

Почему нет транзакции, хотя методы аннотированы @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"/>


person user1781028    schedule 16.09.2013    source источник


Ответы (1)


При использовании Spring и Spring управляемых транзакций никогда не вмешивайтесь в hibernate.current_session_context_class свойство ЕСЛИ вы не используете JTA.

Spring по умолчанию устанавливает свою собственную реализацию CurrentSessionContext (SpringSessionContext), однако, если вы установите его самостоятельно, этого не произойдет. В основном нарушает правильную интеграцию транзакций.

Единственная причина для изменения этого параметра - всякий раз, когда вы хотите использовать управляемые транзакции JTA, вам необходимо настроить это для правильной интеграции с JTA.

person M. Deinum    schedule 17.09.2013
comment
Хорошо, я восстановил старую конфигурацию, но теперь, как я могу решить org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions, который связан с многопоточностью? В основном у меня есть потоки, и они оба пытаются выполнить save() операцию над одним и тем же объектом, который содержит коллекцию. Может, мне стоит избежать этой ситуации и сделать только одну из них? - person user1781028; 17.09.2013
comment
Почему у вас один объект, который сохраняется несколькими потоками. - person M. Deinum; 17.09.2013
comment
Хорошо, я удалил одну из операций сохранения. Но что, если по каким-то причинам они мне действительно нужны? - person user1781028; 18.09.2013
comment
Вы должны предотвратить совместное использование одного и того же экземпляра объекта между потоками. Каждый поток должен работать со своим собственным экземпляром (т.е. читать строку из базы данных). - person M. Deinum; 18.09.2013
comment
@ M.Deinum, но что, если я получу эту ошибку: org.hibernate.HibernateException: CurrentSessionContext не настроен! когда я не настраиваю hibernate.current_session_context_class? Я читал, что этот беспорядок в транзакции автоматической обработки, но без этого не сработает. - person Mr Jedi; 20.02.2014
comment
Тогда я предполагаю, что вы не используете Spring для настройки SessionFactory или, по крайней мере, не свойства. - person M. Deinum; 20.02.2014
comment
@ M.Deinum - я понимаю, что это старый тред, но, как заявил г-н Джедай, я сталкиваюсь с той же проблемой, что и г-н Джедай - я создаю фабрики сеансов с помощью кода, а не с помощью весенней инъекции - если у вас есть время, вы можете мне помочь пожалуйста, с этим: stackoverflow.com/questions/ 27344393 / - person satish marathe; 10.12.2014
comment
В чем разница между транзакциями, управляемыми JTA, и транзакциями, управляемыми Spring? - person Amit Das; 03.06.2015