Spring Transactions and hibernate.current_session_context_class
Asked Answered
C

1

23

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"/>

Chromatin answered 16/9, 2013 at 16:25 Comment(0)
C
39

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.

Chasten answered 17/9, 2013 at 6:21 Comment(8)
Ok, I restored the old configuration, but now, how can I solve the org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions that comes with multithreading? Basically I have to threads, and they both try to do a save() operation on the same object, which contains a collection. Maybe I have to avoid this situation and do only one of them?Chromatin
Why do you have a single object, which is being saved by multiple threads.Chasten
Ok I removed one of the save operations. But what if, for some particular reasons, I really needed them both?Chromatin
YOu should prevent the same object instance being shared between threads. Each thread should operate on its own instance (i.e. read the row from the database).Chasten
@M.Deinum but what if I get this error: org.hibernate.HibernateException: No CurrentSessionContext configured! when I dont configure hibernate.current_session_context_class ? I read that this mess in auto handle transaction but without it won't work.Trstram
Then I assume you aren't using Spring to configure the SessionFactory or at least not property.Chasten
@M.Deinum - I do realize this is a old thread but as Mr Jedi stated - I am facing exact same issue as Mr Jedi - I create session factories through code and not through spring injection - if you have some time can you help me please with this : #27344893Kerrykersey
What is the difference between JTA managed transactions and spring managed transaction ?Farant

© 2022 - 2024 — McMap. All rights reserved.