【问题标题】:Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session [duplicate]休眠错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联[重复]
【发布时间】:2011-04-06 07:07:18
【问题描述】:

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

我也遇到了和user差不多的问题。

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

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

显然,问题在于我从 db 检索到的对象与我想要更新的对象具有相同的 id(应该是这样),但它们不是相同的对象!

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

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    任选其一:

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

    2 - 不要创建新实体进行更新,而是使用旧实体并对其进行编辑。

    3 - 从会话中分离你的第一个实体 - session.evict(myEntity)

    【讨论】:

    • 感谢您的想法,但我不想关闭会话,而且我的架构不允许我更新旧对象(除了付出很多努力)
    • @Sven 你可以从会话中分离实体吗?
    • 不起作用:javax.servlet.ServletException:org.hibernate.SessionException:会话已关闭!
    【解决方案2】:

    您的问题是您之前加载的对象仍然存在于您的休眠会话中。我看到了两种应对方法。

    1.) 告诉休眠会话将您修改的对象与会话中的对象合并

    session.merge(object)
    

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

    【讨论】:

    • merge() 对我不起作用。我尝试了 clear() 和 evict(object) 成功
    • @Silentbang。是的,我必须同时执行“clear()”和“evict(object)”。似乎一个或另一个应该单独工作,但需要两者。
    【解决方案3】:

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

    显然,问题在于我从 db 检索到的对象与我要更新的对象具有相同的 id(应该是这样),但它们不是相同的对象!

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

    【讨论】:

    • 不,它们是相同的逻辑对象/相同的实体,但 java 为它们提供了不同的对象 ID
    • <id>s 是如何生成的?你用的是什么方案?
    【解决方案4】:

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

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

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

    解决方法很简单:

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

    合并首先返回您在会话中拥有的对象的实例。

    【讨论】:

    • 这真的很有帮助。我试过 session.evict() 很多次都没有成功。
    猜你喜欢
    • 2010-11-07
    • 2011-04-02
    • 2013-04-21
    • 2014-04-16
    • 2020-04-11
    • 2012-09-30
    • 2012-06-06
    • 2011-03-16
    相关资源
    最近更新 更多