Hibernate Envers с Spring с использованием HibernateTemplate

Я пытаюсь настроить Envers в среде Spring. Все работает нормально, когда я извлекаю сеанс вручную из SessionFactory и помещаю все в транзакцию:

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();

Приведенный выше код вставляет данные в таблицу TestEntity, а также обновляет таблицы AUD и REVINFO.

Однако, когда я обновляю таблицу с помощью нашего DAO, с таблицами, специфичными для Envers, ничего не происходит. Я подозреваю, что причиной может быть использование HibernateTemplate в DAO.

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

Моя конфигурация Spring для SessionFactory выглядит так:

<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>

Я прочитал довольно много записей на форумах и в блогах, включая эту, на который есть ссылка из часто задаваемых вопросов Envers, но ничего из упомянутого там, кажется, не работает в моей ситуации.

Кто-нибудь знает, можно ли настроить Envers для совместной работы с Spring, используя HibernateTemplate (вместо JPA)? Какие части моей конфигурации мне нужно изменить? На какую часть документации/API Hibernate стоит обратить внимание в этом контексте (боюсь, я еще не эксперт по Hibernate)? Может ли кто-нибудь предоставить образец кода рабочей конфигурации?

Я использую Spring 3.0.1 и Hibernate 3.5.1.


person martin    schedule 08.02.2011    source источник
comment
HibernateTemplate не делает ничего интересного, просто немного упрощает Hibernate API. На самом деле, текущая документация Spring рекомендует вам не использовать HibernateTemplate, в этом больше нет необходимости. Я думаю, что ваша проблема в другом.   -  person skaffman    schedule 08.02.2011
comment
Как вы управляете транзакциями?   -  person axtavt    schedule 08.02.2011


Ответы (1)


Проблема вызвана тем фактом, что Envers полагается на правильное управление транзакциями, тогда как HibernateTemplate возвращается в режим «автоматической фиксации» при использовании вне транзакции, так что Envers в этом случае не работает.

Поэтому вам необходимо настроить управление транзакциями, чтобы использовать Envers. Когда методы HibernateTemplate вызываются внутри транзакции, Envers работает нормально.

См. также:

person axtavt    schedule 08.02.2011
comment
Спасибо за Ваш ответ. В моем приложении был определен диспетчер транзакций, но в моем интеграционном тесте отсутствовала некоторая конфигурация. Добавление @TransactionConfiguration(transactionManager = transactionManager, defaultRollback = false) и @Transactional в мой тестовый класс и расширение AbstractTransactionalTestNGSpringContextTests, наконец, сделали свое дело. - person martin; 16.02.2011