Java HibernateTemplate与Envers一起工作吗?如果是,怎么做?
我试图在一个同样使用Hibernate和Spring的项目上使用Envers,我非常欣赏HibernateTemplate提供的代码缩减 我在JPA下配置了Envers,经过一些调整后,我能够让EnversHibernateToolTask Ant任务(包括审计表)生成模式。但是,当我编写代码时,例如: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
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>