作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我像这样实现了一个 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 时,它会导致堆栈跟踪以消息 Session is closed
结束。
问题似乎是事件在事务中间触发,在导致回滚的异常情况之前,并且由于事件监听器必须使用它自己的 session ,它也不会被回滚。
有什么方法可以确保事件监听器的 Action 也被回滚吗?我刚刚选择了一个在交易中发生得太早的事件吗?在可能发生回滚的最后一点之后是否有我应该捕捉的事件,从而确保在发生回滚时插入 AuditTrail
不会触发?
最佳答案
一直没人回复,我自己研究,初步的解决方案如下:
public class AuditListener implements PostInsertEventListener {
private static final long serialVersionUID = -966368101369878522L;
@Override
public void onPostInsert(PostInsertEvent event) {
if (event.getEntity() instanceof Auditable) {
Session session = null;
try {
session = event.getPersister().getFactory().getCurrentSession();
Auditable auditableEntity = (Auditable)event.getEntity();
session.save(new AuditTrail(auditableEntity.getClass().getSimpleName(),
auditableEntity.getId(), auditableEntity.getStatus(),
auditableEntity.getLastModified()));
} catch (HibernateException he) {
System.out.println("Horrible error: " + he.getMessage());
session.getTransaction().rollback();
}
}
}
}
请注意,我正在从 PostInsertEvent
的 SessionFactoryImplementor
调用“getCurrentSession()
”。我不确定这是否是一个潜在的危险策略,我也不确定将 rollback()
调用保留在那里是否有意义,但它似乎起作用并且没有其他人提供过更好的解决方案。好了。
关于java - Hibernate 事件监听器 - 回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12149870/
我是一名优秀的程序员,十分优秀!