Hibernate持久化和错误处理工作流程

时间:2017-03-08 11:58:14

标签: java hibernate error-handling

我是hibernate的新手,我对错误处理和持久性工作流程有疑问。我有以下遗留代码。

public void doPersist(Contact out){
  contactValidator.validationOne(out);
  entityManager.persist(out);
  contactValidator.validationTwo(out);
  contactValidator.validationThree(out);
}

ContactValidator是一个用于验证Contact的类,它会在每个验证方法中抛出多个业务异常。我不喜欢方法doPersist的构造方式。为什么它首先调用entityManager.persist然后验证对象?如果某些验证方法中存在异常,则应回滚数据。 Hibernate如何在已经调用persist时回滚数据?

1 个答案:

答案 0 :(得分:1)

我个人并不关心如何编写doPersist方法,因为我可以看到几种更清洁的替代品,避免使用这种多余的方法。

要回答您的具体问题,回滚的神奇之处在于交易的运作方式。事务只不过是一系列作为单个工作单元执行的操作,必须遵循原子,一致,隔离和持久(例如ACID)。

当事务处于活动状态且尚未提交时,如果抛出异常,则异常处理会告知事务忘记了它被告知要执行的操作。

Session session = sessionFactory.openSession();
try {
  session.getTransaction().begin();
  // do whatever work you want to do here
  session.getTransaction().commit();
}
catch ( Throwable t ) {
  if ( session.getTransaction().isActive() ) {
    session.getTransaction().rollback();
  }
  throw t;
}
finally {
  session.close();
}

所以在这段代码中,即使事务正在尝试提交并抛出异常,catch子句也会看到它处于活动状态并将事务回滚,从而告诉数据库丢弃所有刚刚被问到的工作表演。

现在,我想触摸您的 ContactValidator

我的猜测是你的ContactValidator与Bean验证的方式密切相关。它基本上会查看bean的状态,并确保没有任何不一致的期望,如果是这样,则断言有异常。

hibernate-validatorhibernate-core结合使用时,您可以免费获得bean验证,因为Hibernate会插入验证器框架并对以下事件执行验证操作

  • PrePersistEvent
  • PreUpdateEvent
  • PreRemoveEvent

如您所见,开箱即用的 post 事件支持没有。这是有道理的,因为您通常希望在实际保存或更新数据库行之前满足约束。这就是为什么我发现你的第二和第三次接触验证方法很奇怪。

除此之外,如果您确实需要一些插入后或更新后验证,您可以使用在PostInsertEvent上注册的自定义Hibernate侦听器轻松绑定到现有的bean验证器侦听器以进行这些操作。 PostUpdateEvent组调用bean验证。