HibernateTemplate与Envers一起使用吗?如果是这样,怎么样?

时间:2009-10-30 03:34:34

标签: java hibernate spring jpa hibernate-envers

我正在尝试在也使用Hibernate和Spring的项目上使用Envers - 我很欣赏HibernateTemplate提供的代码减少。

我在JPA下配置了Envers,经过一些调整后,我能够获得EnversHibernateToolTask​​ Ant任务(包括审计表)生成的模式。但是,当我编写代码如:

    hibernateTemplate.saveOrUpdate(f);

数据是持久的,但审计表中没有任何内容。相反,如果我写:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    em.persist(f);
    em.getTransaction().commit();

然后数据进入审计表(但我宁愿使用以前的语法 - 我知道使用JPA的EntityManager将代码与Hibernate解耦,但它很简单并不能解决麻烦 - 改变ORM引擎不是我最疯狂的这个项目的梦想。)

检查我的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>

这是我的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>

有没有人对这里发生的事情有所暗示?谢谢!

2 个答案:

答案 0 :(得分:2)

HibernateTemplate有它的JPA对应物JpaTemplate,它提供了一个非常相似的功能。

Envers不能与HibernateTemplate一起使用的原因是因为它依赖于使用EntityManager时触发的JPA事件(您可以看到在persistence.xml中声明的侦听器)。理论上可以编写代码来在使用HibernateTemplate时从Hibernate会话中触发这些事件,但是相当复杂。

答案 1 :(得分:1)

你需要做的只是在你的Dao中调用@Transactional或调用dao.save()/ update方法的服务。

即使您注册了eventlistener,除非您使用Spring FW的Transcational,否则不会触发这些事件。 Spring必须知道并告诉hibernate这些事件被触发了。