Hibernate错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话关联

时间:2010-08-31 13:52:42

标签: java hibernate orm

  

可能重复:
  Hibernate: different object with the same identifier value was already associated with the session

我遇到了与user几乎相同的问题。

在我的情况下,我从db加载一个实体,我将此实体转换为DataTransferObject,然后我想编辑一个属性,之后我将其转换回entityObject,然后我更新该实体并且hibernate抛出以下错误:

Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

显然,问题是我从db检索的对象具有与我想要更新的对象相同的id(就像它应该的那样)但是那些不是同一个对象!

如何管理? 谢谢你的帮助...

4 个答案:

答案 0 :(得分:30)

您的问题是您之前加载的对象仍然存在于您的休眠会话中。我认为有两种方法可以解决这个问题。

1。)告诉hibernate会话将修改后的对象与会话中的对象合并

session.merge(object)

2。)在将更新的对象写入会话之前,将旧对象踢出会话。 session.clear()可能有用。

答案 1 :(得分:14)

这是Hibernate的常见问题。即使您从会话中删除它,该对象仍将保留在Hibernate PersistanceContext中,您将遇到同样的问题。问题还来自于session.contains使用对象相等而不是equals()来比较对象......

故事如下:您有对象A和对象B,它们是相同的逻辑对象,但是您的Java堆中有两个不同的对象。你很久以前在会话中对对象A做了一些事情。

现在,如果你执行session.delete(B),你将获得异常,因为你试图删除一个与A具有相同主键但不是A的对象。

解决方案很简单:

Object findAAgain=session.merge(B);
session.delete(findAAgain);

合并首先返回会话中对象的实例。

答案 2 :(得分:4)

选择其中之一:

1 - 您可以在加载实体后关闭会话并打开新会话以进行更新

2 - 不使用新的Entity进行更新,而是使用旧的Entity进行更新。

3 - 将您的第一个实体与会话分开 - session.evict(myEntity)

答案 3 :(得分:0)

除了在会话中调用clear()之外,听起来您可能对使用Hibernate的方式有疑问:

  

显然,问题是我从db检索的对象与我想要更新的对象具有相同的ID(就像它应该的那样)但是那些不是同一个对象!

您的意思是说您有两个具有相同ID的不同实体吗?如果是这样,那么你应该找到一个唯一标识不同实体的字段。