Java HibernateTemplate与Envers一起工作吗?如果是,怎么做?

Java HibernateTemplate与Envers一起工作吗?如果是,怎么做?,java,hibernate,spring,jpa,hibernate-envers,Java,Hibernate,Spring,Jpa,Hibernate Envers,我试图在一个同样使用Hibernate和Spring的项目上使用Envers,我非常欣赏HibernateTemplate提供的代码缩减 我在JPA下配置了Envers,经过一些调整后,我能够让EnversHibernateToolTask Ant任务(包括审计表)生成模式。但是,当我编写代码时,例如: hibernateTemplate.saveOrUpdate(f); 数据被持久化,但没有任何内容进入审计表。相反,如果我写: EntityManager em = emf.c

我试图在一个同样使用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>

有人知道这里发生了什么吗?谢谢大家!

HibernateTemplate有它的JPA对应物,它提供了相当类似的功能


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

您需要做的就是将@Transactional放入Dao或调用Dao.save()/update方法的服务中


即使您注册了eventlistener,也不会触发这些事件,除非您使用SpringFW的Transconational。Spring必须知道并告诉hibernate这些事件已经触发

非常好-使用JpaTemplate应该可以做到这一点。它没有我想要的全部功能(特别是,我有一些需要分页的代码,并通过findByCriteria实现了这一点,它允许对调用注入限制),但至少我有了一个起点。非常感谢。这有点像黑客,但如果您将JpaTemplate的exposeNativeEntityManager设置为true,则可以使用其
executeFind()
方法将
EntityManager
传递给
JpaCallback
作为
HibernateEntityManager
并使用后者的
getSession()
进行基于条件的查询。此外,在Envers1.2.1(最新版本)中,
AuditEventListener
实现了常规Hibernate的事件监听器,这意味着实际上应该可以将其配置为普通Hibernate(无JPA)。您需要去掉
entityManagerFactory
persistence.xml
,而是使用
eventListeners
map将所有侦听器配置为sessionFactory的一部分-查看
LocalSessionFactoryBean
了解详细信息;然后您就可以使用
HibernateTemplate
。请注意,我没有测试这个。嗯。。。。必须检查两种方法。我认为如果我真的需要使用Hibernate函数性,我宁愿完全放弃JPA,但我将首先尝试在不公开HibernateEntityManager或尝试这种新函数性的情况下完成这一切。谢谢。请看下面我的评论。
<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>