2012-04-16 11 views
8

sto migrando il mio progetto da Spring 3,0 + ibernazione 3.6.x per S3.1 + H4.1Primavera 3.1 + Hibernate 4.1 Propagation.Supports problema

mio nuovo codice è il seguente

<context:component-scan base-package="x.y.z"> 
</context:component-scan> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
<props> 
    <prop key="hibernate.dialect">org.hibernate.dialect.x</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    <prop key="hibernate.hbm2ddl.auto">update</prop> 
    <prop key="hibernate.show_sql">true</prop> 
    </props> 
    </property> 
     <property name="annotatedClasses"> 
     <list> 
     <value>x.y.z.entities.Student</value>   
     </list> 
    </property> 
    </bean> 

<bean id="transactionManager" 
      class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 

<aop:config> 
    <aop:pointcut id="daoServicePoint" 
      expression="execution(* x.y.z.StudentDao.*(..))"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="daoServicePoint"/> 
    </aop:config> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="save*" propagation="REQUIRED"/> 
     <tx:method name="update*" propagation="REQUIRED"/> 
     <tx:method name="delete*" propagation="REQUIRED"/> 
    <tx:method name="get*" propagation="SUPPORTS" read-only="true"/> 
    </tx:attributes> 
    </tx:advice> 

Quando si esegue il metodo marcatore getStudent come supporti e sola lettura mi sto

org.hibernate.HibernateException: No Session found for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024) 

'usato per essere ok con la Primavera 3.0 e Hibernate 3.6.x ora è stato cambiato. I undeastood dei forum di Spring che richiedono la transazione mark OBBLIGATO se ho bisogno di usare sessionFactory.getCurrentSession();

Ho usato la tecnica di livello inferiore per ottenere la massima velocità simultanea nel mio codice. Quando si eseguono operazioni che richiedono diversi get/save/aggiornamento/query ho fatto nel modo seguente:

  1. chiamato metodo contrassegnato come SUPPORTS.
  2. Tutte le richieste di ricezione vengono contrassegnate come SUPPORTS all'interno del primo metodo .
  3. quindi ha avviato query contrassegnate come REQUIRED all'interno dello stesso metodo e questo è un punto in cui inizia la mia transazione di back-through.

Ho ottenuto un buon miglioramento delle prestazioni utilizzando questa tecnica, ma contrassegnando tutti i miei metodi come OBBLIGATORIA lo distrugge.

Come può aggirarlo?

+0

Definire "distrugge" le prestazioni. Quella "tecnica di livello inferiore" non suona come se stesse per darti un notevole miglioramento delle prestazioni se nel passaggio 3 hai ancora bisogno di aprire una transazione, forse con l'eccezione delle entità caricate nel passaggio 2 che non sono soggette a controllo sporco e caching. O il miglioramento delle prestazioni che hai visto nel sistema nel suo complesso, a causa di molte chiamate a metodi che non sono mai arrivati ​​al passaggio 3? –

+0

Per curiosità: hai misurato il guadagno in termini di prestazioni del tuo piccolo trucco? Dubito che ne valga la pena, a meno che tu non abbia delle serie richieste di prestazioni del tuo prodotto. –

+0

@RasmusFranke, per fortuna non è qualcosa che ho inventato. Ho appena letto questo articolo http://www.ibm.com/developerworks/java/library/j-ts5/index.html –

risposta

0

Penso che si possa ancora contrassegnare la transazione come readonly. non so se ha un impatto sulle prestazioni.

+0

No. Non puoi. –

+1

Perché? sto usando @Transactional (readOnly = true) e sta funzionando bene con Hibernate 4 e Spring 3.1 –

+0

Spiacente, per causa puoi :) –

3

ho incontrato lo stesso problema quando si sperimentano Spring e Hibernate 3/4.

Sembra che questo è un problema noto, descritto nel seguente collegamento JIRA.

https://jira.springsource.org/browse/SPR-9020

sembra che la versione Hibernate 4 di SpringSessionContext non si apre una nuova sessione, se non v'è alcuna transazione/sessione aperta e il metodo chiamato esistente @Transactional è configurato con propagazione = Propagation.SUPPORTS.

+0

questo sta accadendo anche a me .. cosa hai fatto? – thiagoh

+0

@thiagoh Mi scuso per la risposta tardiva.Non ho avuto la necessità di lavorare su una soluzione per questo perché non ho riscontrato il problema. Ho cercato il motivo per cui non funzionava. Ci sono un paio di suggerimenti su come aggirare questo problema nella sezione commenti della JIRA a cui ho fatto riferimento. Uno di questi è quello di cambiare la propagazione in qualcosa di diverso (ad esempio PROPAGATION_REQUIRED). L'altro consiste nell'implementare una classe CurrentSessionContext personalizzata che crea una Sessione in questo caso e associarla a SessionFactory che verrà utilizzata. – mess

Problemi correlati