我像这样实现了一个休眠事件监听器:
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();
但是当我尝试使用该会话时,它会导致堆栈跟踪以 message 结尾Session is closed
。
问题似乎是事件在事务中间触发,在导致回滚的异常情况之前,并且由于事件侦听器必须使用自己的会话,它也不会回滚。
有没有办法确保事件监听器的动作也被回滚?我是否刚刚选择了在交易中过早发生的事件?是否有一些事件发生在可能发生回滚的最后一点之后,从而确保在AuditTrail
发生回滚时不会触发插入?