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

2022-08-31 09:37:26

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

  • 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"

在我研究这个问题的过程中,我看到有人建议使用 ,但是当我这样做时,任何“冲突”对象都会作为空白对象插入到数据库中,所有值都设置为 null。显然,这不是我们想要的。session.merge()

[编辑]我忘记提到的另一件事是(出于我无法控制的体系结构原因),每个读取或写入都需要在单独的会话中完成。


答案 1

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

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

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


答案 2

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


推荐