Hibernate Envers with Spring using HibernateTempla

2019-05-23 11:04发布

问题:

I'm trying to setup Envers in a Spring environment. Everything works fine, when I retrieve a session manually from the SessionFactory and put everything inside a Transaction:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
TestEntity test = new TestEntity();
test.setTest("REV1");
session.save(test);
tx.commit();
tx = session.beginTransaction();
test.setTest("REV2");
session.save(test);
tx.commit();

The above code inserts data into the TestEntity-table and also updates the AUD- and REVINFO-tables.

However, when I update the table using our DAO, nothing happens to the Envers-specific tables. I suspect the reason might be using HibernateTemplate in the DAO.

HibernateDaoSupport dao;
...
HibernateTemplate hibernateTemplate = dao.getHibernateTemplate();
TestEntity test = new TestEntity();
test.setTest("REV1");
hibernateTemplate.saveOrUpdate(test);
test.setTest("REV2");
hibernateTemplate.saveOrUpdate(test);

My Spring-config for the SessionFactory looks like this:

<bean id="test-sessionFactory" class=...>
    <property name="dataSource" ref="test-dataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>
    <property name="eventListeners">
    <map>
        <entry key="post-insert" value-ref="enversListener" />
        <entry key="post-update" value-ref="enversListener" />
        <entry key="post-delete" value-ref="enversListener" />
        <entry key="pre-collection-update" value-ref="enversListener" />
        <entry key="pre-collection-remove" value-ref="enversListener" />
        <entry key="post-collection-recreate" value-ref="enversListener" />
    </map>
</property>
</bean>

I have read quite a lot of forum- and blog entries including this one, that is linked to from the Envers FAQ, but nothing mentioned there seems to work in my situation.

Does anyone know, if it's possible to configure Envers to work together with Spring using HibernateTemplate (instead of JPA)? What parts of my configuration do I need to change? What part of the Hibernate documentation/API is worth looking at in this context (I'm afraid I'm not an Hibernate expert yet)? Could someone provide a code sample of a working configuration?

I'm using Spring 3.0.1 and Hibernate 3.5.1.

回答1:

The problem is caused by the fact that Envers relies on proper transaction management, whereas HibernateTemplate falls back to "auto-commit" mode when used outside of transaction, so that Envers doesn't work in this case.

Therefore you need to configure transaction management in order to use Envers. When HibernateTemplate's methods are called inside a transaction, Envers works fine.

See also:

  • 10. Transaction Management
  • 13.3 Hibernate