Работает ли HibernateTemplate с Envers?Если да, то каким образом?

StackOverflow https://stackoverflow.com/questions/1647894

Вопрос

Я пытаюсь использовать Envers в проекте, который также использует Hibernate и Spring - и я очень ценю сокращение кода, предлагаемое HibernateTemplate.

Я настроил Envers под JPA, и после нескольких настроек я смог получить схему, сгенерированную муравьиной задачей EnversHibernateToolTask (включая таблицы аудита).Однако, когда я пишу такой код, как:

    hibernateTemplate.saveOrUpdate(f);

данные сохраняются, но в таблицы аудита ничего не поступает.И наоборот, если я напишу:

    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();
    em.persist(f);
    em.getTransaction().commit();

затем данные поступают в таблицы аудита (но я бы предпочел использовать прежний синтаксис - я знаю, что использование EntityManager от JPA отделяет этот код от 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>

и вот мой persistence.xml настройка:

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

У кого-нибудь есть намек на то, что здесь происходит?Спасибо!

Это было полезно?

Решение

HibernateTemplate имеет свой аналог JPA, JpaTemplate ( табличка ) который обеспечивает довольно схожую функциональность.

Причина, по которой Envers не работает с HibernateTemplate, заключается в том, что он полагается на события JPA (вы можете видеть слушателей, объявленных в вашем persistence.xml выше) срабатывает при использовании EntityManager.Теоретически возможно написать код для запуска этих событий из сеанса гибернации при использовании HibernateTemplate, но это довольно сложно.

Другие советы

Все, что вам нужно было сделать, это поместить @Transactional в ваш Dao или сервисы, которые вызывают методы dao.save() / update.

Даже если вы зарегистрируете свой eventlistener, эти события не будут запущены, если вы не используете транскрипцию Spring FW.Spring должен знать и сообщать hibernate, что эти события запущены.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top