我基本上在这个配置中有一些对象(实际的数据模型有点复杂):
a与b之间存在多对多关系(b有 inverse="true"
)
b与c之间存在多对一关系(我有 cascade
设置为 "save-update"
)
c是一种类型/类别表。
另外,我应该提到,主键是由数据库在保存时生成的。
对于我的数据,我有时会遇到这样的问题:a有一组不同的b对象,而这些b对象引用同一个c对象。
当我打电话的时候 session.saveOrUpdate(myAObject)
,我得到一个hibernate错误: "a different object with the same identifier value was already associated with the session: C"
. 我知道hibernate不能在同一个会话中插入/更新/删除同一个对象两次,但是有什么方法可以解决这个问题吗?这种情况似乎并不少见。
在我研究这个问题的过程中,我看到有人建议使用 session.merge()
,但当我这样做时,任何“冲突”对象都会作为空对象插入到数据库中,所有值都设置为null。显然这不是我们想要的。
[编辑]另一件我忘记提到的事情是(由于我无法控制的体系结构原因),每次读写都需要在单独的会话中完成。
21条答案
按热度按时间vnzz0bqm1#
刚看到这条信息,但用的是c代码。不确定它是否相关(尽管与错误消息完全相同)。
我用断点调试代码,并在调试器处于断点时通过私有成员扩展了一些集合。在没有挖掘结构的情况下重新运行代码,错误消息就消失了。看起来,查看私有延迟加载集合的行为使得nhibernate加载了当时不应该加载的东西(因为它们在私有成员中)。
代码本身被 Package 在一个相当复杂的事务中,该事务可以作为该事务(导入过程)的一部分更新大量记录和许多依赖项。
希望能给其他遇到这个问题的人一个线索。
y53ybaqx2#
除了前面的所有答案之外,如果您对类使用value对象时没有在vo transformer类中设置id属性,那么在大型项目中可能会解决这个问题。
2ledvvac3#
确保您的实体与所有Map实体具有相同的生成类型
例如:用户角色
}
模块:
}
带Map的主实体
}
nbnkbykc4#
只要将cascade设置为merge,就可以了。
f45qwnt85#
在hibernate中找到“cascade”atribute并将其删除。当您将“cascade”设置为可用时,它将调用其他与相关类有关系的实体的操作(保存、更新和删除)。所以同样的情况也会发生。它对我起了作用。
yfjy0ee76#
我同意@hemant kumar,非常感谢。根据他的解决办法,我解决了我的问题。
例如:
个人.java
此代码在我的应用程序中总是出错:
A different object with the same identifier value was already associated with the session
,后来我发现我忘了自动增加主键!我的解决方案是在主键上添加以下代码:
0x6upsns7#
这意味着您正试图保存表中引用同一对象的多行。
检查实体类的id属性。
到
ou6hu8tu8#
很可能是因为b对象引用的不是同一个javac对象示例。它们引用的是数据库中的同一行(即相同的主键),但它们是数据库的不同副本。
因此,管理实体的hibernate会话将跟踪哪个java对象对应于具有相同主键的行。
一种方法是确保引用同一行的对象b的实体实际上引用的是c的同一个对象示例。或者关闭该成员变量的级联。这样,当b是持久的时,c不是。不过,您必须分别手动保存c。如果c是一个类型/类别表,那么这样做可能是有意义的。
jfgube3f9#
另一种情况是可以生成相同的错误消息,自定义
allocationSize
:不匹配
在插入过程中可能会导致约束验证(这一点很容易理解)或“具有相同标识符值的不同对象已与会话关联”-这种情况不太明显。
j1dl9f4610#
你只需要做一件事。跑
session_object.clear()
然后保存新对象。这将清除会话(恰当地命名),并从会话中删除有问题的重复对象。zzzyeukh11#
如果让ide中的一个表达式选项卡处于打开状态,该选项卡正在对导致此异常的对象进行hibernate get调用。我想删除同一个对象。另外,delete调用上有一个断点,这似乎是发生此错误所必需的。只需将另一个表达式选项卡设为前选项卡或更改设置,使ide不会在断点处停止,就可以解决此问题。
7xzttuei12#
将注解@generatedvalue添加到要插入的bean中。
uxh89sit13#
我遇到这个问题是因为主键生成错误,当我插入这样一行时:
我将id生成器类更改为identity
k97glaaz14#
在调用update query之前,可能没有设置对象的标识符。
weylhg0b15#
在我的例子中,只有flush()不起作用。我必须在flush()之后使用clear()。