我基本上在这个配置中有一些对象(真正的数据模型有点复杂):
- A 与 B 具有多对多关系。(B 具有
inverse="true"
) - B 与 C 具有多对一关系。(我将
cascade
设置为"save-update"
) - C是一种类型/类别表。
另外,我可能应该提到主键是由数据库在保存时生成的。
对于我的数据,我有时会遇到这样的问题:A 有一组不同的 B 对象,而这些 B 对象引用同一个 C 对象。
当我调用 session.saveOrUpdate(myAObject)
时,我收到一条休眠错误消息: "a different object with the same identifier value was already associated with the session: C"
。我知道休眠不能在同一个会话中两次插入/更新/删除同一个对象,但是有什么办法可以解决这个问题吗?这种情况似乎并不少见。
在我研究这个问题的过程中,我看到人们建议使用 session.merge()
,但是当我这样做时,任何“冲突”对象都会作为空白对象插入到数据库中,所有值都设置为空。显然这不是我们想要的。
[编辑] 我忘记提及的另一件事是(出于我无法控制的体系结构原因),每次读取或写入都需要在单独的会话中完成。
原文由 John 发布,翻译遵循 CC BY-SA 4.0 许可协议
很可能是因为 B 对象没有引用同一个 Java C 对象实例。它们指的是数据库中的同一行(即相同的主键),但它们是它的不同副本。
因此,正在发生的事情是管理实体的 Hibernate 会话将跟踪哪个 Java 对象对应于具有相同主键的行。
一种选择是确保引用同一行的对象 B 的实体实际上引用 C 的同一对象实例。或者关闭该成员变量的级联。这样,当 B 被持久化时,C 就不会被持久化。不过,您必须单独手动保存 C。如果 C 是一个类型/类别表,那么这样做可能是有意义的。