java - 似乎无法摆脱 NonUniqueObjectException

标签 java database hibernate jpa orm

我在 Java Hibernate 中使用 SINGLE_TABLE 继承策略,这里是设置:

Class A

 @Cascade(CascadeType.DELETE_ORPHAN, CascadeType.ALL)
 List<B> Bs; 

B 有一个扩展 B 的子类 Ba。Ba 有一个 B 没有的额外字段。我这样做的原因是只有 Ba 对象(少得多)应该关心这个额外的字段,我想避免在每个 B 对象上都有它的开销。

在保存期间,按照我们的设置方式,我们必须更新以前的 B 对象字段(而不是仅仅更改引用)。所以我们不能做 List of Bs = List of Changed Bs,我们必须通过主键找到每个单独的 B 并更新字段,所以像 B.fields = changedB.fields

出现这个异常的时候是在保存的时候,之前的B对象需要保存为一个带有extra字段的Ba。反向(将以前的 Ba 对象保存到 B)很好,我可以将该额外字段设置为 null 或向下转换。但我似乎找不到将 B 对象变成 Ba 的方法。

我试过了

  • 在保存之前从列表中删除 B 并添加一个 Ba,这就是我遇到此异常的时候。
  • 我什至还尝试将所有字段从 B 交换到需要转换为 B 的 Ba,反之亦然,但这也没有用,我得到了一个异常,因为我更改了这些对象的 Pk .

最佳答案

期间 Session flush the DML operation order是:

  • 插入
  • 更新
  • 集合元素的删除
  • 集合元素的插入
  • 删除

因此,即使您删除该元素并添加一个新元素,插入也会在删除之前运行,从而抛出约束违反异常。

要使其正常工作,您需要在删除之后和将新元素添加回子集合之前手动刷新:

a.removeChild(b);
session.flush();
a.addChild(ba);

remove/addChild 是设置双向关联两侧的实用程序,如果在您的域模型中是这种情况的话。

关于java - 似乎无法摆脱 NonUniqueObjectException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26265539/

相关文章:

java - CXF + wsdl2java + 认证

mysql - MySQL 仍然是免费/开源数据库的不错选择吗?

java - 表中的列由多个物理列名引用

Java:字符串到 ImageIcon?

java - 为什么 IE 11 浏览器对于 jQuery AJAX POST 请求随机有 Content-Length=0?

java - 如何将字符串转换为 fragment 文件名

sql - 如何对 SQL 表列进行验证?

C# IEnumerator/yield 结构可能不好?

postgresql - 如何在为 Hibernate native SQL 查询构建标量投影时注册多个 JDBC Types.OTHER 映射

hibernate - 什么时候在Hibernate中使用@Version和@Audited?