如何使spring-data-envers与Hibernate 3一起使用

时间:2015-06-27 17:20:42

标签: java spring hibernate jpa hibernate-envers

我正在尝试使用spring-data-envers实现实体审核功能。问题是我的公司仍在使用Hibernate 3,看起来像spring-data-envers只适用于Hibernate 4.以下是我得到的错误:

org.springframework.orm.jpa.JpaSystemException: You need to install the org.hibernate.envers.event.AuditEventListener class as post insert, update and delete event listener.; nested exception is org.hibernate.envers.exception.AuditException: You need to install the org.hibernate.envers.event.AuditEventListener class as post insert, update and delete event listener.
    at org.hibernate.envers.AuditReaderFactory.get(AuditReaderFactory.java:71)
    at org.hibernate.envers.AuditReaderFactory.get(AuditReaderFactory.java:85)
    at org.springframework.data.envers.repository.support.EnversRevisionRepositoryImpl.findRevisions(EnversRevisionRepositoryImpl.java:127)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:414)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:399)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:371)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy30.findRevisions(Unknown Source)
    at org.springframework.data.envers.repository.support.RepositoryIntegrationTest.returnsEmptyRevisionsForUnrevisionedEntity(RepositoryIntegrationTest.java:99)

感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

尝试以下配置

在pom.xml中

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-envers</artifactId>
    <version>${hibernate.version}</version>
</dependency>

在spring-hibernate.xml中(或者你给的任何名字)

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
    <list>
        <value>com.yourpackage.model</value>
    </list>
</property>
<property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaProperties">
    <props>
        <prop key="hibernate.hbm2ddl.auto">replace_with_your_</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        <prop key="hibernate.show_sql">${hibernate.show.sql}</prop>
        <prop key="hibernate.format_sql">${hibernate.format.sql}</prop>

        <!-- Envers properties -->
        <prop key="org.hibernate.envers.auditTablePrefix"/>            
        <prop key="org.hibernate.envers.auditTableSuffix">_HISTORY</prop>            
    </props>
</property>

重要内容:

<prop key="org.hibernate.envers.auditTablePrefix"></prop>
<prop key="org.hibernate.envers.auditTableSuffix">_HISTORY</prop>

后缀“_HISTORY”是您选择为数据库表提供的名称,该数据库表将包含您实体的不同版本。最后一个@Audited注释放在需要审核的实体之上。

@Entity
@Table(name = "user")
@Audited
public class User implements Serializable {}

答案 1 :(得分:0)

这是我的项目中的Spring Java Config,它使spring-data-envers工作:

@Configuration
@EnableJpaRepositories(basePackages = "your.repository.package", repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
public class ServiceModelTestSpringConfig {

//.. Spring-JPA-Hibernate setup ..
 @Bean
 public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
   LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
   em.setDataSource(dataSource());
   em.setPackagesToScan("your.entity.package");

   JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
   em.setJpaVendorAdapter(vendorAdapter);
   em.setJpaProperties(additionalProperties());

   return em;
 }

 @Bean
 public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
   JpaTransactionManager transactionManager = new JpaTransactionManager();
   transactionManager.setEntityManagerFactory(emf);

   return transactionManager;
 }

 @Bean
 public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
   return new PersistenceExceptionTranslationPostProcessor();
 }

 @Bean
 public DataSource dataSource() {
   DriverManagerDataSource dataSource = new DriverManagerDataSource();
   dataSource.setDriverClassName("org.h2.Driver");
   // dataSource.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); // Use in-memory database
   dataSource.setUrl("jdbc:h2:~/test/itdata;DB_CLOSE_DELAY=-1"); // Use file database
   dataSource.setUsername("ying");
   return dataSource;
 }

 Properties additionalProperties() {
   Properties properties = new Properties();
   properties.setProperty("hibernate.hbm2ddl.auto", "update");
   properties.setProperty("hibernate.connection.autocommit", "false");
   properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
   // Hibernate Envers Event Listeners
   properties.setProperty("hibernate.ejb.event.post-insert", "org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener");
   properties.setProperty("hibernate.ejb.event.post-update", "org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener");
   properties.setProperty("hibernate.ejb.event.post-delete", "org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener");
   properties.setProperty("hibernate.ejb.event.pre-collection-update", "org.hibernate.envers.event.AuditEventListener");
   properties.setProperty("hibernate.ejb.event.pre-collection-remove", "org.hibernate.envers.event.AuditEventListener");
   properties.setProperty("hibernate.ejb.event.post-collection-recreate", "org.hibernate.envers.event.AuditEventListener");
   return properties;
 }
 // .. EOF Spring-JPA-Hibernate setup ..

}