次のように Hibernate Event Listener を実装しました。
public class AuditListener implements PostInsertEventListener {
private static final long serialVersionUID = -966368101369878522L;
@Override
public void onPostInsert(PostInsertEvent event) {
if (event.getEntity() instanceof Auditable) {
StatelessSession session = null;
try {
session = event.getPersister().getFactory().openStatelessSession();
Auditable auditableEntity = (Auditable)event.getEntity();
session.beginTransaction();
session.insert(new AuditTrail(auditableEntity.getClass().getSimpleName(),
auditableEntity.getId(), auditableEntity.getStatus(),
auditableEntity.getLastModified()));
session.getTransaction().commit();
} catch (HibernateException he) {
System.out.println("Horrible error: " + he.getMessage());
session.getTransaction().rollback();
} finally {
if (session != null) {
session.close();
}
}
}
}
}
オブジェクトを挿入AuditTrail
した直後にオブジェクトをデータベースに挿入するだけAuditable
です。
私が抱えている問題は、オブジェクトを永続化するトランザクション中に何らかの例外的な状況が発生した場合に発生しAuditable
ます。トランザクションはロールバックされますが、それでもAuditTrail
レコードが挿入されます。
私はこれを回そうとしました:
StatelessSession session = event.getPersister().getFactory().openStatelessSession();
これに:
Session session = event.getSession();
しかし、そのセッションを使用しようとすると、メッセージで終わるスタック トレースが発生しますSession is closed
。
問題は、ロールバックにつながる例外的な状況の前に、トランザクションの途中でイベントが発生し、イベント リスナーが独自のセッションを使用する必要があるため、ロールバックされないことです。
イベントリスナーのアクションもロールバックされるようにする方法はありますか? トランザクションの早い段階で発生するイベントを選択しましたか? ロールバックが発生する可能性のある最後のポイントの後に発生するイベントをキャッチして、ロールバックが発生したAuditTrail
場合に挿入がトリガーされないようにするイベントはありますか?