2013-09-16 16 views
18

Ich habe eine Spring 3.2-Anwendung, die Hibernate 4 und Spring-Transaktionen verwendet. Alle Methoden funktionierten großartig und ich konnte korrekt auf die Datenbank zugreifen, um Entitäten zu speichern oder abzurufen. Dann führte ich einige Multithreading, und da jeder Thread db zugriff ich die folgende Fehlermeldung aus dem Ruhezustand erhalten:Spring-Transaktionen und hibernate.current_session_context_class

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

ich aus dem Internet gelesen, dass ich <prop key="hibernate.current_session_context_class">thread</prop> meine Hibernate-Konfiguration hinzuzufügen, aber jetzt jedes Mal, wenn ich versuche, die db zugreifen erhalte ich:

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

jedoch meine Service-Methoden mit @Transactional kommentiert werden, und alle adaequat war vor dem hinzufügen von <prop key="hibernate.current_session_context_class">thread</prop>.

Warum gibt es keine Transaktion, obwohl die Methoden mit @Transactional gekennzeichnet sind? Wie kann ich dieses Problem lösen?

Hier ist meine Hibernate-Konfiguration (einschließlich der Sitzungskontext-Eigenschaft):

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

Antwort

31

Wenn Feder und verwaltet Transaktionen mit nie mess around mit dem hibernate.current_session_context_class Eigenschaft SOFERN Sie verwenden JTA.

Spring wird standardmäßig seine eigene CurrentSessionContext Implementierung (die SpringSessionContext), aber wenn Sie es selbst einstellen dies wird nicht der Fall sein. Im Grunde bricht die ordnungsgemäße Transaktionsintegration.

Der einzige Grund für das Ändern dieser Einstellung ist, wann immer Sie JTA-verwaltete Transaktionen verwenden möchten, dann müssen Sie dies so einrichten, dass es ordnungsgemäß in JTA integriert wird.

+0

Ok, ich habe die alte Konfiguration wiederhergestellt, aber jetzt, wie kann ich die 'org.hibernate.HibernateException: Illegal versuchen, eine Sammlung mit zwei offenen Sitzungen zu assoziieren, die mit Multithreading kommt? Grundsätzlich muss ich Threads, und sie beide versuchen, eine 'save()' Operation für das gleiche Objekt, das eine Sammlung enthält. Vielleicht muss ich diese Situation vermeiden und nur einen von ihnen tun? – user1781028

+1

Warum haben Sie ein einzelnes Objekt, das von mehreren Threads gespeichert wird? –

+0

Ok Ich habe eine der Speicheroperationen entfernt. Was aber, wenn ich sie aus bestimmten Gründen wirklich beide brauchte? – user1781028

Verwandte Themen