Hibernate(JPA付き)とHibernate Enversを使用してオブジェクトの履歴を保持します。 Webアプリケーションは多くのスレッドを実行し、それらの一部は他のアプリケーションからのRMIメソッド呼び出しによって作成され、その一部はアプリケーション自身によって作成され、一部はHTTP要求を処理するために作成されます(ビューを生成します)。私たちのweb.xmlが含まれているので、Spring + Hibernate + Envers +マルチスレッド - セッションが閉じられる
我々はまた、セッションを管理するための表示パターンでオープンセッションを使用します。
<filter>
<filter-name>openEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
データベースは、それらのすべては春によって注入EntityManagersを持っている、のDAOを使用してアクセスされます。
@PersistenceContext
protected EntityManager em;
@PersistenceUnit
protected EntityManagerFactory emf;
私たちがHibernate Enversを使用することを決定する前に、すべてはうまくいっていました。ビュー生成スレッドではないスレッドがオブジェクトの古いバージョンを取得するコードを実行すると、例外がスローされます。スレッド "スケジューラ" org.hibernate.SessionExceptionで
@Override
public O loadByRevision(Long revision, Long id) {
@SuppressWarnings("unchecked")
O object = (O) AuditReaderFactory.get(em).createQuery().forEntitiesAtRevision(getBaseClass(), revision.intValue())
.add(AuditEntity.id().eq(id)).getSingleResult();
return object;
}
例外: セッションが閉じられています! でorg.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:129) でorg.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1776) org.hibernate.envers.tools.queryました。 org.hibernate.envers.query.impl.EntitiesAtRevisionQuery.listでQueryBuilder.toQuery(QueryBuilder.java:226) でorg.hibernate.envers.query.impl.AbstractAuditQuery.buildQuery(AbstractAuditQuery.java:92) ( EntitiesAtRevisionQuery.java:108) でorg.hibernate.envers.query.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:110) (...)
上記のコードをビュー生成スレッドで実行するとうまくいきます。また、DAOのnon-enversコードはすべてのスレッドで正常に動作します。例えば、
@Override
public O load(Long id) {
final O find = em.find(getBaseClass(), id);
return find;
}
以下のスニペットは問題なくRMIスレッドで実行することができます。
エンティティマネージャのメソッドを例外なしで呼び出すことはできますが、そのエンティティマネージャでEnversのAuditReaderFactoryを使用することはできません。おそらくエンティティマネージャのメソッドを呼び出すと一時的なセッションが作成されると思っていましたが、Enversを使用してもそれは起こりません。
この問題を解決する最善の方法は何ですか(AuditReaderFactoryをすべてのスレッドから使用できるようにするには)?