我的对象:http://pastebin.com/FWEGwcL0
我需要阻止添加已存在的couple(name; surname)行。 即:我可以添加(约翰;布朗),(约翰;怀特),(露易丝;布朗),但我应该防止添加另一个(约翰;布朗)。
当我保存对象时,我会保存一个List。 这意味着如果我把密钥放在DB上让这对(name,surname)唯一,我担心当我保存对象列表时,如果一个失败,所有其他值也都会失败。
我该如何防止这种情况?
非常感谢!
答案 0 :(得分:0)
不幸的是,如果你有附加实例,JPA中的异常是不可恢复的。
来自规范:
3.3.2事务回滚对于事务范围和扩展持久性上下文,事务回滚导致所有预先存在 托管实例和删除实例[31]变得分离。该 实例的状态将是实例的状态 该事务被回滚。通常是事务回滚 导致持久化上下文处于不一致状态 回滚点。特别是版本属性和状态 生成的状态(例如,生成的主键)可能不一致。 以前由持久性上下文管理的实例 (包括那些持久的新实例 因此,交易)可能无法以与其他方式相同的方式重复使用 分离的对象 - 例如,它们可能在传递给合并时失败 操作。[32]
这意味着一旦遇到异常,就不能将该会话用于任何进一步的数据库操作。
这意味着您必须创建一个新会话,然后再次启动您的交易。
如果您直接使用hibernate API来管理您的交易,Hibernate也是如此。
12.2.3。异常处理如果Session抛出异常(包括任何SQLException),则立即回滚数据库 事务,调用Session.close()并丢弃Session实例。 会话的某些方法不会使会话保持一致 州。 Hibernate抛出的异常都不能被视为可恢复的。 确保通过在finally中调用close()来关闭Session 块。
处理此问题的一种方法是,您不使用托管实例而是使用分离实例,在这种情况下,无论是否成功,您将在每次数据库操作后关闭会话或entityManager。
在这种情况下,一旦关闭会话,您的对象就会分离,并且进一步的Exception不会对它们产生任何影响。
遇到了不错的article