martes, agosto 27, 2013

@Transactional(readOnly=true) no funciona en Spring JPA/Hibernate

Estoy trabajando en una aplicacion Spring que fue creada con Spring Roo el cual realiza la configuracion inicial de todo lo referente a Spring, hibernate, mvc, log4j, etc. El problema es que al parecer algo faltaba en esa configuracion ya que mis servicios marcados con la @Transactional(readOnly=true) no parecian realmente respetar esa anotacion.

En la aplicacion tengo un EntityListener que modifica los campos de tipo String despues de cargar los entities usando un metodo @PostLoad, el problema es que aunque la transaccion esta marcada como readOnly = true, hibernate detectaba esos cambios y actualizaba el entity al final de la transaccion. Esto no deberia ser asi.

Investigando un poco encontre que hay una configuracion del entityManagerFactory que no tenia en mi applicationContext.xml, al parecer es requerida para que hibernate haga caso del flag readOnly, la configuracion que no funcionaba era esta:

    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="persistenceUnitName" value="persistenceUnit"/>
        <property name="dataSource" ref="dataSource"/>
    </bean>

Lo que falta aqui es el jpaVendorAdapter, lo agregue a la configuracion quedando asi:

    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="persistenceUnitName" value="persistenceUnit"/>
        <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
        <property name="dataSource" ref="dataSource"/>
    </bean>

Despues de eso hibernate ya no intento guardar mi entity en las transacciones marcadas con @Transactional(readOnly=true)