Работает ли HibernateTemplate с Envers? Если так, то как? - PullRequest
2 голосов
/ 30 октября 2009

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

Я настроил Envers под JPA, и после нескольких настроек мне удалось создать схему, сгенерированную задачей Ant 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>

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

Ответы [ 2 ]

2 голосов
/ 30 октября 2009

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

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

1 голос
/ 25 октября 2010

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

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

...