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!

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top