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

user1781028
  • 1,478
  • 4
  • 22
  • 45

1 Answers1

38

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.

Kayvan Tehrani
  • 3,070
  • 2
  • 32
  • 46
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • 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? – user1781028 Sep 17 '13 at 16:40
  • 1
    Why do you have a single object, which is being saved by multiple threads. – M. Deinum Sep 17 '13 at 18:11
  • Ok I removed one of the save operations. But what if, for some particular reasons, I really needed them both? – user1781028 Sep 18 '13 at 12:22
  • 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). – M. Deinum Sep 18 '13 at 12:42
  • 1
    @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. – Mr Jedi Feb 20 '14 at 15:54
  • Then I assume you aren't using Spring to configure the SessionFactory or at least not property. – M. Deinum Feb 20 '14 at 19:29
  • @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 : http://stackoverflow.com/questions/27344393/transaction-management-using-hibernate-with-weblogic – satish marathe Dec 10 '14 at 14:11
  • 3
    What is the difference between JTA managed transactions and spring managed transaction ? – Amit Das Jun 03 '15 at 04:32