似乎无法摆脱 NonUniqueObjectException
Posted
技术标签:
【中文标题】似乎无法摆脱 NonUniqueObjectException【英文标题】:Can't seem to get rid of NonUniqueObjectException 【发布时间】:2014-10-08 20:10:06 【问题描述】:我在 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 对象保存为带有额外字段的 Ba。反向(将以前的 Ba 对象保存到 B)很好,我可以将那个额外的字段设置为 null 或向下转换。但我似乎找不到将 B 对象变成 Ba 的方法。
我试过了
从列表中删除 B 并在保存之前添加一个 Ba,即出现此异常。 我什至尝试将 B 中的所有字段交换到需要转换为 B 的 Ba 中,反之亦然,但这也不起作用,我得到了一个异常,因为我更改了这些对象的 Pk .【问题讨论】:
【参考方案1】:Session flush the DML operation order 期间是:
插入 更新 集合元素的删除 集合元素的插入 删除因此,即使删除元素并添加新元素,插入也会在删除之前运行,从而引发约束冲突异常。
要使其正常工作,您需要在删除之后和将新元素添加回子集合之前手动刷新:
a.removeChild(b);
session.flush();
a.addChild(ba);
remove/addChild 是设置双向关联双方的实用程序,如果在您的域模型中是这种情况。
【讨论】:
不幸的是,我正在执行此操作的代码部分没有会话上下文。我这样做的地方很简单,将集合的新列表设置为旧列表,以便休眠可以保存新列表。那么没有其他方法可以将 B 对象设置为 Ba (带有额外字段)吗?我的意思是我只需要向我知道存在于数据库(和子类)中但不在对象本身上的字段添加一个额外的值。 重新分配新集合将删除所有子对象并添加新对象。这不是有效的,在你的情况下也无效。它导致先插入,然后再删除。因此,您需要将逻辑推送到您拥有 Session 的位置。以上是关于似乎无法摆脱 NonUniqueObjectException的主要内容,如果未能解决你的问题,请参考以下文章
(os/kern) 无效功能 (20) 无效名称(15) - 我似乎无法摆脱这些错误
无法摆脱 xib 文件中的 Group Table View Background Color deprecated 警告