Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Transactions and hibernate.current_session_context_class

Tags:

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

like image 597
user1781028 Avatar asked Sep 16 '13 16:09

user1781028


People also ask

What is the difference between spring transaction and Hibernate transaction?

Hibernate deals with database specific transactions, whereas spring provides a general transaction management service. @Transactional is a nice way of configuring transaction management behaviour.

What is Current_session_context_class in Hibernate?

hibernate. context. CurrentSessionContext ) and a new configuration parameter ( hibernate. current_session_context_class ) have been added to allow pluggability of the scope and context of defining current sessions.

Can Hibernate session have multiple transactions?

Obviously, you can. A hibernate session is more or less a database connection and a cache for database objects. And you can have multiple successive transactions in a single database connection. More, when you use a connection pool, the connection is not closed but is recycled.

Does @transactional close session?

@Transactional helps you to extend scope of Session . Session is open first time when getCurrentSession() is executed and it is closed when transaction ends and it is flushed before transaction commits.


1 Answers

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.

like image 191
M. Deinum Avatar answered Sep 23 '22 18:09

M. Deinum