HibernateTemplate funziona con Envers? Se é cosi, come?
-
22-07-2019 - |
Domanda
Sto cercando di utilizzare Envers su un progetto che utilizza anche Hibernate e Spring - e apprezzo molto la riduzione del codice offerta da HibernateTemplate.
Ho configurato Envers in JPA e dopo alcune modifiche sono stato in grado di far generare lo schema dall'attività Ant di EnversHibernateToolTask ??(comprese le tabelle di controllo). Tuttavia, quando scrivo codice come:
hibernateTemplate.saveOrUpdate(f);
i dati sono persistenti, ma nulla va nelle tabelle di controllo. Al contrario, se scrivo:
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(f);
em.getTransaction().commit();
quindi i dati vanno alle tabelle di controllo (ma preferirei usare la precedente sintassi - so che usare EntityManager di JPA disaccoppia quel codice da Hibernate, ma è semplice non ripagare la seccatura - cambiare il motore ORM non è nel mio più selvaggio sogni per questo progetto.)
Potrebbe essere utile verificare la mia configurazione applicationContext.xml
:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="projetox" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.w2it.projetox.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
...
</bean>
ed ecco la mia configurazione persistence.xml
:
<persistence-unit name="projetox" transaction-type="RESOURCE_LOCAL">
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!-- Hibernate Envers -->
<property name="hibernate.ejb.event.post-insert"
value="org.hibernate.envers.event.AuditEventListener" />
<property name="hibernate.ejb.event.post-update"
value="org.hibernate.envers.event.AuditEventListener" />
<property name="hibernate.ejb.event.post-delete"
value="org.hibernate.envers.event.AuditEventListener" />
<property name="hibernate.ejb.event.pre-collection-update"
value="org.hibernate.envers.event.AuditEventListener" />
<property name="hibernate.ejb.event.pre-collection-remove"
value="org.hibernate.envers.event.AuditEventListener" />
<property name="hibernate.ejb.event.post-collection-recreate"
value="org.hibernate.envers.event.AuditEventListener" />
</properties>
</persistence-unit>
Qualcuno ha un suggerimento su cosa sta succedendo qui? Grazie!
Soluzione
HibernateTemplate ha la sua controparte JPA, JpaTemplate che fornisce una funzionalità abbastanza simile.
Il motivo per cui Envers non funziona con HibernateTemplate è perché si basa su eventi JPA (puoi vedere i listener dichiarati nel tuo persistence.xml
) attivati ??quando si utilizza EntityManager. In teoria è possibile scrivere codice per attivare quegli eventi dalla sessione di Hibernate quando viene utilizzato HibernateTemplate, ma è piuttosto coinvolto.
Altri suggerimenti
Tutto quello che dovevi fare era inserire @Transactional nel tuo Dao o nei servizi che chiamano i metodi dao.save () / update.
Anche se registri il tuo listener di eventi, questi eventi non vengono generati a meno che tu non usi transcazionali di Spring FW. La primavera deve sapere e dire al letargo che questi eventi vengono lanciati.