0

我的对象: http: //pastebin.com/FWEGwcL0

我需要防止添加已经存在的夫妇(姓名;姓氏)的行。即:我可以添加 (John; Brown)、(John; White)、(Louise; Brown),但我应该阻止添加另一个 (John; Brown)。

当我保存对象时,我会保存一个列表。这意味着如果我将密钥放在 DB 上让这对夫妇(姓名,姓氏)唯一,我担心当我保存对象列表时,如果一个失败,所有其他值也会失败。

我怎样才能防止这种情况?

非常感谢!

4

1 回答 1

0

不幸的是,如果您附加了实例,JPA 中的异常是不可恢复的。

从规范:

3.3.2 事务回滚 对于事务范围和扩展的持久性上下文,事务回滚会导致所有预先存在的托管实例和已删除的实例[31] 分离。实例的状态将是事务回滚时实例的状态。事务回滚通常会导致持久性上下文在回滚时处于不一致的状态。特别地,版本属性的状态和生成的状态(例如,生成的主键)可能不一致。因此,以前由持久性上下文管理的实例(包括在该事务中持久化的新实例)可能无法以与其他分离对象相同的方式重用——例如,它们在传递给合并操作时可能会失败。 [32 ]

这意味着一旦遇到异常,您就不能将该会话用于任何进一步的数据库操作。

这意味着您必须创建一个新会话,然后再次开始您的事务。

如果您直接使用 hibernate API 来管理事务,那么 Hibernate 也是如此。

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

处理此问题的一种方法是您不使用托管实例,而是使用分离实例,在这种情况下,您将在每次数据库操作成功与否之后关闭会话或 entityManager。

在这种情况下,一旦关闭会话,您的对象就会分离,进一步的异常不会对它们产生任何影响。

看到一篇不错的文章

于 2012-06-01T18:40:12.887 回答