【问题标题】:Is this a bug in org.hibernate.internal.SessionImpl?这是 org.hibernate.internal.SessionImpl 中的错误吗?
【发布时间】:2016-08-25 22:32:08
【问题描述】:

org.hibernate.internal.SessionImpl 继承层次结构中的具体祖先类以这样的方式覆盖 Object.equals(Object),使得行“/* 3 */" 下面返回 false?


package deduper;

import org.hibernate.*;

public class SessionEqualsPuzzler { 

    public static void main( String... fubar ){

        Session aSession  /* = ... Get a valid session instance from SessionFactory... */; /* 1 */

        assert ( aSession == aSession ) : "This error message WILL NEVER be shown..."; /* 2 */

        boolean isEqual = aSession.equals( aSession ); /* 3 */

        assert ( isEqual  ) : "This error message SHOULD never be shown — but it is anyway for some unknown reason...: " + isEqual; /* 4 */

    }

}

如果您使用“-ea” - 启用断言 - 开关运行上述操作,则会抛出一个 AssertionError标记为“/* 4 */”的行。

我已经搜索了所有我能想到的地方。但据我所知,SessionImpl 似乎没有 - 它的任何祖先 - 覆盖 Object.equals(Object).

令人费解的是,“/* 2 */”行的计算结果为真,但“/* 3 */”行却没有!

据我了解,“shallow”身份检查 ("==") 正是默认的 Object.equals(Object) 所做的。对吧?

我的工作假设是 SessionImpl 不会覆盖其继承层次结构中的任何位置的默认 Object.equals(Object)

还有其他人知道为什么上面的 SessionImpl.equals(Object) 调用评估为假吗?


顺便说一句,我正在使用 Hibernate 4.3.11.Final,因为它物有所值。


更新Hibernate have acknowledged the existence of the bug, resolved it super quickly——再次感谢@SteveEbersole——and the fix is scheduled to be released in version 5.2.3

【问题讨论】:

  • 执行System.out.println(aSession.getClass())时会打印什么?
  • “据我了解,“浅层”身份检查 ("==") 正是默认 Object.equals(Object) 所做的。对吧?否 - 除了原语,“==”运算符只会验证对象是否是完全相同的对象。如果你想要 .equals 那么你需要调用 .equals。
  • @JBNizet - System.out.println(aSession.getClass()) prints class com.sun.proxy.$Proxy14 顺便说一句,我正在使用 Hibernate 4.3.11.Final,因为它物有所值。
  • 好的。所以它不是 SessionImpl 的一个实例。它是一个动态代理,这个代理的调用处理程序决定如何实现equals()。显然,它决定总是返回 false。
  • 还有@deduper,因为这是“我的工作,不是你的”......哇。从你的观点来看,有太多事情是错误的,甚至无法开始进入。拥抱开源精神的方式。

标签: java hibernate


【解决方案1】:

所以,从技术上讲……不。不,它不是“org.hibernate.internal.SessionImpl 中的错误”。然而,基于线程的当前会话处理如何处理 2 个会话相等的问题存在一个错误。我解决了这个问题;请参阅有关您打开的 HHH-11067 问题的讨论。

【讨论】:

    【解决方案2】:

    此错误是已知的并已报告,跟踪地址为 https://hibernate.atlassian.net/browse/HHH-7528。正如 @JBNizet 在 cmets 中提到的,它是 Hibernate 使用动态代理的一部分。

    该错误目前仅标记为影响 5.x 之前的版本,不再维护。如果您可以验证它仍然存在于 Hibernate 5.x 中,请在错误跟踪器上报告。

    【讨论】:

    • 谢谢@Douglas。有人告诉我这一定是一个实际的错误。感谢您对我的支持 :¬) 我再次使用 Hibernate 4.3.11.Final,物有所值。
    • 因为 \@Douglas 证实了我的假设,即我看到了一个实际的错误——实际上回答了我标题中的问题——我将继续接受 \@Douglas 的回答。但我仍然感谢@JBNizet 向我介绍了 Hibernate 对代理的使用。
    • 这个bug和实体代理有关,不是Session代理,这是两个不相关的东西。毕竟,@deduper 你使用 IBM JVM 吗?道格拉斯提到的错误只能在那里重现......
    • FWIW HHH-7528 与 Hibernate 的 JDBC 对象代理有关(很像 DataSource 或 JCA 所做的),而不是实体的代理。只是为了澄清一些混乱。
    猜你喜欢
    • 2013-05-04
    • 2011-09-28
    • 2017-07-23
    • 2012-09-15
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多