HibernateTemplate は Envers で動作しますか?もしそうなら、どのようにして?
-
22-07-2019 - |
質問
Hibernate と Spring も使用するプロジェクトで Envers を使用しようとしています。HibernateTemplate によって提供されるコード削減に非常に感謝しています。
JPA で Envers を構成し、いくつかの調整を行った後、EnversHibernateToolTask Ant タスクによってスキーマ (監査テーブルを含む) を生成できるようになりました。ただし、次のようなコードを書くと、
hibernateTemplate.saveOrUpdate(f);
データは永続化されますが、監査テーブルには何も送信されません。逆に、私が次のように書くと、
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(f);
em.getTransaction().commit();
その後、データが監査テーブルに送られます (ただし、私は前の構文を使用したいと思っています。JPA の EntityManager を使用すると、そのコードが 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 に相当するものがあります。 JPAテンプレート これはかなり似た機能を提供します。
Envers が HibernateTemplate で動作しない理由は、Envers が JPA イベントに依存しているためです (リスナーが HibernateTemplate で宣言されていることがわかります) persistence.xml
上記)EntityManager が使用されるときにトリガーされます。HibernateTemplate の使用時に Hibernate セッションからこれらのイベントをトリガーするコードを記述することは理論的には可能ですが、かなり複雑です。
他のヒント
あなたがする必要があるのは、dao.save()/ update メソッドを呼び出す Dao またはサービスに @Transactional を置くことだけです。
イベントリスナーを登録した場合でも、Spring FW の Transcational を使用しない限り、これらのイベントは発生しません。Spring は、これらのイベントが発生したことを認識し、Hibernate に通知する必要があります。