【问题标题】:Good ideas for debugging Hibernate Session/Transaction errors?调试 Hibernate 会话/事务错误的好主意?
【发布时间】:2011-10-28 18:09:53
【问题描述】:

我使用 Hibernate 已经有一段时间了,并且已经习惯了大多数常见的错误消息。大多数人直接指出了这个问题,但我一直遇到这个问题:

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

我了解错误(会话有两个具有相同 ID 的不同对象),但我真的不知道调试代码以查找问题根源的好方法。通常,我会查看当前正在更改的代码,并寻找加载一个对象并手动创建另一个对象的位置,希望能在我的逻辑中找到一个简单的错误。但是,我目前正在使用一个不是我编写的、不熟悉的并且没有文档的代码集。我能想到的唯一解决方案是逐行检查代码,希望能找到错误。您知道调试此错误的更好方法吗?

此外,我得到的确切错误来自对saveOrUpdate() 的调用,这让我想知道它是否在调用save() 而应该调用update()。有没有什么方法可以查看 Hibernate 在当前 Session 中的对象以进行调试?

【问题讨论】:

    标签: hibernate debugging transactions hibernate-session


    【解决方案1】:

    saveOrUpdate 调用 update 如果分离的实体已经有一个 ID。 update 然后尝试将给定的分离实体附加到会话。由于会话中只能有一个给定实体的实例,如果在调用 saveOrUpdate 时已经在会话中加载了实体(使用 loadget 或查询),则'会得到这个异常。

    saveOrUpdate 通常应该是打开会话后首先要做的事情之一。如果您必须在更新之前加载实体,您应该使用merge。我通常更喜欢在所有情况下使用merge,因为它不太容易出错。

    您可以使用session.getStatistics().getEntityKeys() 了解会话中的内容。

    【讨论】:

    • “并且更新尝试将给定的分离实体附加到会话。”那不应该说 save 而不是 update 吗?
    • 没有。 Save 使瞬态实例持久化,并将实体附加到会话。更新采用分离的、修改的实例并尝试将其附加到会话。如果会话中已经存在具有相同 ID 的持久化实例,则抛出异常。
    【解决方案2】:

    您可能还想在 Session.Flush 函数中设置断点并检查哪些对象存储在持久化器中。 Here 您可能会找到一些关于如何跟踪会话打开和会话关闭事件的信息 - 您可能需要仔细检查 SessionImpl 对象的 PersistenceContext 属性和 OnFlush 事件。

    要使用源代码进行调试,您无需重新编译所有 NHibernate 源 - 您可以将 pdb 文件与 zip 源文件绑定(查看http://lowleveldesign.wordpress.com/2011/10/02/debugging-nhibernate-prepare-symbol-files/)。

    【讨论】:

    • 感谢您的回复,但我没有使用 nhibernate。我仍然会考虑在 Java 上下文中使用您的建议。
    猜你喜欢
    • 2016-12-17
    • 2011-03-15
    • 1970-01-01
    • 2012-07-26
    • 2015-11-16
    • 1970-01-01
    • 2011-01-02
    • 2014-11-05
    • 1970-01-01
    相关资源
    最近更新 更多