我實現了一個Hibernate的事件監聽器,像這樣:Hibernate的事件監聽器 - 回滾
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();
}
}
}
}
}
它所做的就是將任何Auditable
對象後立即插入一個AuditTrail
對象到數據庫中。
我遇到的問題是在交易過程中有任何異常情況持續存在Auditable
對象時:事務回滾,但仍插入AuditTrail
記錄。
我試圖把這樣的:
StatelessSession session = event.getPersister().getFactory().openStatelessSession();
進入這個:
Session session = event.getSession();
但是,當我嘗試使用它會導致該消息在Session is closed
結束的堆棧跟蹤。
問題似乎是事件在事務中間觸發,在導致回滾的異常情況之前觸發,並且由於事件偵聽器必須使用自己的會話,所以它也不會回滾。
有什麼方法可以確保事件監聽器的操作也被回滾?我剛剛選擇了事務發生得太早的事件嗎?是否有一個事件我應該捕捉髮生回滾的最後一個點後發生的事件,從而確保在發生回滾時不會觸發插入AuditTrail
?
查看jboss envers,它是用於審計跟蹤的。 – ewernli