2013-09-16 33 views
18

Ho un'applicazione Spring 3.2 che utilizza Hibernate 4 e Transactions. Tutti i metodi funzionavano alla grande e potevo accedere correttamente al database per salvare o recuperare entità. Poi, mi ha introdotto alcune multithreading, e dal momento che ogni thread stava accedendo al db stavo ottenendo il seguente errore da Hibernate:Transazioni di primavera e hibernate.current_session_context_class

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

Ho letto dal web che ho da aggiungere <prop key="hibernate.current_session_context_class">thread</prop> alla mia configurazione di Hibernate, ma ora ogni volta che provo ad accedere al db ottengo:

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

Tuttavia i miei metodi di servizio sono annotati con @Transactional, e tutto stava funzionando benissimo prima l'aggiunta di <prop key="hibernate.current_session_context_class">thread</prop>.

Perché non esiste alcuna transazione sebbene i metodi siano annotati con @Transactional? Come posso risolvere questo problema?

Ecco la mia configurazione di Hibernate (inclusa la proprietà contesto di sessione):

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

risposta

31

Quando si utilizzano le transazioni di primavera e la primavera gestito mai pasticciare con la proprietà hibernate.current_session_context_classMENO si utilizza JTA.

Spring imposta automaticamente la propria implementazione CurrentSessionContext (il SpringSessionContext), tuttavia se lo si imposta da solo, questo non sarà il caso. Rompere fondamentalmente la corretta integrazione delle transazioni.

L'unico motivo per modificare questa impostazione è ogni volta che si desidera utilizzare le transazioni gestite JTA, quindi è necessario impostarlo per integrarsi correttamente con JTA.

+0

Ok, ho ripristinato la vecchia configurazione, ma ora, come posso risolvere 'org.hibernate.HibernateException: tentativo illegale di associare una raccolta con due sessioni aperte? Che viene fornito con il multithreading? Fondamentalmente ho dei thread, ed entrambi cercano di fare un'operazione 'save()' sullo stesso oggetto, che contiene una collezione. Forse devo evitare questa situazione e fare solo una di queste? – user1781028

+1

Perché si dispone di un singolo oggetto, che viene salvato da più thread. –

+0

Ok Ho rimosso una delle operazioni di salvataggio. Ma cosa succede se, per qualche ragione particolare, avevo davvero bisogno di entrambi? – user1781028

Problemi correlati