2012-04-16 18 views
8

Estoy migrando mi proyecto de Primavera 3.0 + hibernación 3.6.x a S3.1 + H4.1Primavera 3.1 + Hibernate 4.1 Propagation.Supports tema

mi nuevo código es la siguiente

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

Cuando se ejecuta el método getStudent marcador como soportes y leer sólo yo estoy

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) 

Solía ​​estar bien con Spring e Hibernate 3.0 3.6.x ahora se ha cambiado. No me entendí de los foros de Spring que cortan Necesito una transacción de marca REQUERIDA si necesito usar sessionFactory.getCurrentSession();

Utilicé la técnica de nivel inferior para obtener la máxima velocidad simultánea en mi código. Cuando las operaciones que requieren varios get/guardar/actualizar/consultas lo hice de la siguiente manera realización:

  1. llamado método marcado como SUPPORTS.
  2. Realizado todas las consultas de obtención que también están marcadas como SUPPORTS dentro de primer método.
  3. y luego inició las consultas que marcaron como REQUIRED dentro del mismo método y este es un punto donde comienza mi transacción de retroceso reversible.

Obtuve una buena mejora en el rendimiento utilizando esta técnica, pero marcar todos mis métodos según lo REQUERIDO lo destruye.

¿Cómo puede solucionarlo?

+0

Define el rendimiento "destruye". Esa "técnica de nivel inferior" no parece que le dará mucha mejora en el rendimiento si en el paso 3 aún necesita abrir una transacción, tal vez con la excepción de las entidades cargadas en el paso 2 que no estén sujetas a revisión sucia y almacenamiento en caché ¿O fue la mejora de rendimiento que vio en el sistema como un todo, debido a muchas llamadas a métodos que nunca llegaron al paso 3? –

+0

Por curiosidad: ¿ha medido el rendimiento de su pequeño truco? Dudo que valga la pena el esfuerzo a menos que tenga serias exigencias de rendimiento de su producto. –

+0

@RasmusFranke, afortunadamente no es algo que inventé. Acabo de leer este artículo. http://www.ibm.com/developerworks/java/library/j-ts5/index.html –

Respuesta

0

Creo que todavía puede marcar la transacción como de solo lectura. no estoy seguro de si tiene un impacto en el rendimiento.

+0

No. No puede. –

+1

¿Por qué? estoy usando @Transactional (readOnly = true) y está funcionando bien con Hibernate 4 y la primavera 3.1 –

+0

Lo siento, porque usted puede :) –

3

me encontré con el mismo problema cuando se experimenta con Spring e Hibernate 3/4.

Parece que este es un problema conocido, que se describe en el siguiente enlace JIRA.

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

Parece que la versión de Hibernate 4 de SpringSessionContext no se abre una nueva sesión si no hay ninguna transacción/sesión abierta y el método llamado existentes @Transactional está configurado con propagación = Propagation.SUPPORTS.

+0

esto me está pasando a mí también ... ¿qué ha hecho? – thiagoh

+0

@thiagoh Pido disculpas por la respuesta tardía.No he tenido la necesidad de trabajar en una solución para esto porque no he encontrado el problema. Solo busqué la razón por la cual esto no funcionaba. Hay un par de sugerencias sobre cómo solucionar este problema en la sección de comentarios de la JIRA a la que hice referencia. Uno de ellos es cambiar la propagación a algo diferente (por ejemplo, PROPAGATION_REQUIRED). El otro es implementar una clase de CurrentSessionContext personalizada que crea una sesión en este caso y asociarla a la SessionFactory que no utilizará. – mess

Cuestiones relacionadas