Hibernate事件监听器 - 回滚 [英] Hibernate Event Listeners - Rollback

查看:110
本文介绍了Hibernate事件监听器 - 回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了一个像这样的Hibernate事件监听器:

I implemented a Hibernate Event Listener like so:

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 对象插入数据库。

All it does is insert an AuditTrail object into the database right after inserting any Auditable object.

我遇到的问题是在交易过程中出现任何类型的异常情况时,会出现 Auditable 对象:事务被回滚,但我仍然得到 AuditTrail 记录已插入。

The problem I am having comes when there is any sort of exceptional situation during the transaction that persists the Auditable object: the transaction is rolled back, but I still get an AuditTrail record inserted.

我试图将其转为:

StatelessSession session = event.getPersister().getFactory().openStatelessSession();

进入:

Session session = event.getSession();

但是当我尝试使用该会话时,会导致堆栈跟踪以消息<$结尾c $ c>会话已关闭。

But when I attempt to use that session it results in a stack trace that ends in the message Session is closed.

问题似乎是事件在特殊情况发生之前触发导致回滚,并且由于事件监听器必须使用自己的会话,它也不会被回滚。

The problem seems to be that the event fires in the middle of the transaction, before the exceptional situation that results in the rollback, and since the Event Listener has to use its own session, it doesn't also get rolled back.

是否有某种方法可以确保事件监听器的操作也会回滚吗?我刚刚选择了在交易过早发生的事件吗?是否有一些我应该捕获的事件发生在可能发生回滚的最后一点之后,从而确保在发生回滚时不会触发 AuditTrail 的插入?

Is there some way to make sure the action of the Event Listener is also rolled back? Have I just chosen an event that occurs too early in the transaction? Is there some event I should be catching that happens after the last point at which a rollback could happen, thus ensuring that the insertion of the AuditTrail will not trigger if a rollback occurs?

推荐答案

由于没有人回复,我一直在自行研究,我的初步解决方案如下:

Since nobody ever replied, I kept researching on my own, and my initial solution is as follows:

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() code>。我不确定这是否是一个潜在的危险策略,而且我也不确定在那里保持 rollback()调用是否有意义,但它似乎起作用,没有人提供更好的解决方案。你去吧。

Note that I'm calling "getCurrentSession()" from the PostInsertEvent's SessionFactoryImplementor. I'm not really sure if this is a potentially dangerous strategy or not, and I'm also not sure if it makes sense to keep that rollback() call in there, but it seems to function and no one else ever supplied a better solution. So there you go.

这篇关于Hibernate事件监听器 - 回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆