Hibernate Error: org.hibernate.NonUniqueObjectException: 具有相同标识符值的不同对象已与会话关联

2022-08-31 08:38:34

我有两个用户对象,当我尝试保存对象时使用

session.save(userObj);

我收到以下错误:

Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]

我正在使用创建会话

BaseHibernateDAO dao = new BaseHibernateDAO();          

rtsession = dao.getSession(userData.getRegion(),
                           BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);

rttrans = rtsession.beginTransaction();
rttrans.begin();

rtsession.save(userObj1);
rtsession.save(userObj2);

rtsession.flush();
rttrans.commit();

rtsession.close(); // in finally block

我也试过做之前保存,还是没有运气。session.clear()

这是第一次在用户请求出现时我获取会话对象,所以我明白为什么说该对象存在于会话中。

有什么建议吗?


答案 1

我多次遇到此错误,可能很难追踪...

基本上,休眠说的是,你有两个对象具有相同的标识符(相同的主键),但它们不是同一个对象。

我建议你分解你的代码,即注释掉位,直到错误消失,然后把代码放回去,直到它回来,你应该找到错误。

它通常通过级联保存发生,其中对象 A 和 B 之间存在级联保存,但对象 B 已与会话相关联,但与 A 上的 B 实例不同。

您使用的是哪种主密钥生成器?

我问这个错误的原因是,你如何告诉休眠来确定对象的持久状态(即对象是否是持久的)。发生此错误的原因可能是休眠正在尝试持久化已持久的对象。实际上,如果您使用 save 休眠状态,则会尝试并持久保存该对象,并且可能已经存在一个具有与会话关联的相同主键的对象。

假设您有一个休眠类对象,用于基于主键组合(列 1 和列 2)的具有 10 行的表。现在,您已经在某个时间点从表中删除了 5 行。现在,如果您尝试再次添加相同的 10 行,而休眠尝试将对象保留在数据库中,则将添加已删除的 5 行而不会出现错误。现在,已经存在的其余 5 行将引发此异常。

因此,简单的方法是检查您是否更新/删除了表中作为某物一部分的任何值,然后您是否尝试再次插入相同的对象


答案 2

这只是休眠产生比解决更多的问题的一个点。在我的例子中,有许多对象具有相同的标识符0,因为它们是新的并且没有一个。数据库生成它们。在某处,我读到0信号Id未设置。持久保存它们的直观方法是迭代它们并说休眠以保存对象。但你不能那样做 - “当然你应该知道冬眠是这样那样工作的,因此你必须这样做。所以现在我可以尝试将Ids更改为Long而不是long,然后看看它是否有效。最后,使用自己的简单映射器更容易做到这一点,因为休眠只是一个额外的不透明的负担。另一个例子:尝试从一个数据库中读取参数并将其保存在另一个数据库中,迫使您手动完成几乎所有工作。但是,如果您无论如何都必须这样做,那么使用休眠只是额外的工作。


推荐