Hibernate事务从另一个事务抛出异常

时间:2014-10-06 04:37:50

标签: java sql oracle hibernate transactions

我试图使用Hibernate保存数据。一切都发生在同一个会话中。逻辑如下:

1)开始交易并尝试保存:

try
{

  session.getTransaction().begin();
  session.save(result);
  session.getTransaction().commit();
}
catch (Exception e)
{
  session.getTransaction().rollback();
  throw e;
}

2)如果新记录违反完整性约束,则在外部包装器方法中捕获异常,打开另一个事务并查询更多数据

catch (ConstraintViolationException e)
{
  if ("23000".equals(e.getSQLException().getSQLState()))
  {
    ...

    session.getTransaction().begin();
    Query query = session.createQuery("from Appointment a where a.begin >= :begin and a.end <= :end");
    query.setDate("begin", date);
    query.setDate("end", DateUtils.addDays(date, 1));

    List results = query.list();
    session.getTransaction().commit();

问题是,当第二个事务执行query.list时,它会引发一个异常,该异常应该与之前的事务相关联。

SQLIntegrityConstraintViolationException:ORA-00001:唯一约束

我应该查询来自其他会话的数据,还是将两个交易隔离开来的另一种方式?

谢谢!

3 个答案:

答案 0 :(得分:1)

如果出现异常,则不应使用相同的会话,必须关闭会话并为第二个操作使用不同的会话。这在hibernate文档中给出:

13.2.3 Exception Handling

  

如果Session抛出异常,包括任何SQLException,   立即回滚数据库事务,调用Session.close()   并丢弃Session实例。 Session的某些方法不会   使会话保持一致状态。没有例外   Hibernate可以被视为可恢复的。确保会话将   通过在finally块中调用close()来关闭。

答案 1 :(得分:0)

希望Exception类是所有类型的异常的基础,因此如果它被放置在它之前将被捕获并且异常处理的其余部分被隔离。

答案 2 :(得分:0)

你可以尝试用session.persist方法替换session.save(),希望这可以解决你的问题。有关这两种方法的详细信息,请参阅以下链接

What's the advantage of persist() vs save() in Hibernate?