【问题标题】:How to make spring-data-envers work with Hibernate 3如何使 spring-data-envers 与 Hibernate 3 一起使用
【发布时间】:2015-06-27 17:20:41
【问题描述】:

我正在尝试使用 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)

感谢任何帮助。

【问题讨论】:

    标签: java spring hibernate jpa hibernate-envers


    【解决方案1】:

    尝试以下配置

    在 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 {}
    

    【讨论】:

    • 你在哪里注册这些 Hibernate Envers 事件?
    • 事件在数据库中注册。 Hibernate Envers 将为每个被审计的实体创建一个表。
    • 我认为从 Hibernate Envers 4 开始,不需要从您的项目中注册事件。但不是 Hibernate Envers 3 或更早版本。
    【解决方案2】:

    这是我项目中的 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 ..
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-13
      • 2023-03-25
      • 2013-03-05
      • 2018-03-18
      • 2017-07-09
      • 2011-03-28
      • 1970-01-01
      • 2019-03-07
      • 2015-08-31
      相关资源
      最近更新 更多