休眠错误:具有相同标识符值的不同对象已与会话相关联

新手上路,请多包涵

我基本上在这个配置中有一些对象(真正的数据模型有点复杂):

  • 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 许可协议

阅读 549
2 个回答

很可能是因为 B 对象没有引用同一个 Java C 对象实例。它们指的是数据库中的同一行(即相同的主键),但它们是它的不同副本。

因此,正在发生的事情是管理实体的 Hibernate 会话将跟踪哪个 Java 对象对应于具有相同主键的行。

一种选择是确保引用同一行的对象 B 的实体实际上引用 C 的同一对象实例。或者关闭该成员变量的级联。这样,当 B 被持久化时,C 就不会被持久化。不过,您必须单独手动保存 C。如果 C 是一个类型/类别表,那么这样做可能是有意义的。

原文由 jbx 发布,翻译遵循 CC BY-SA 3.0 许可协议

只需将级联设置为 MERGE,就可以解决问题。

原文由 0x4ndy 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题