【问题标题】:Working with Collections and Hibernate使用集合和 Hibernate
【发布时间】:2013-12-02 15:39:06
【问题描述】:

我遇到了一个问题,我无法从 HashMap 中获取值,但我确信,我想要获取值的关键是在地图中(但不是同一个实例)。 所以这就是我所拥有的: 我有一个 HiberKey 和一个 HiberVal。

public class HiberKey {
    private int id;
}

public class HiberVal {
  private int id;
}

当程序运行时,它会时不时地进行事务处理,有时我得到一个 Hashmap 和一个 HiberKey single_key。这里的问题是,我想执行 map.get(single_key) 我总是得到一个空值,但是我很确定,地图中有相同的值(不是相同的引用,还有来自休眠会话的事务)。 我首先想到的是 equals & hashcode,但是这些方法已经在 HiberKey 中实现了。

一种解决方案是用 key.id 而不是 hiberkey 填充地图并调用 map.get(single_key.id),但我认为这不是 hibernate 的想法,而且我在地图中使用 Hashmaps 得到了相当复杂的结构等等,如果我用整数填充它们,它就不再那么方便和可读了

有没有人有建议,为什么会发生这种情况? 感谢您的建议。

休眠版本:3.5.3

@Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof BabelKey)) {
      return false;
    }
    return ((BabelKey) obj).id == id;
  }

  @Override
  public int hashCode() {
    return String.valueOf(id).hashCode();
  }

// 更新:

好的,这是一个示例,其中我使用额外的 out.println 调试迭代地图,在输出中您可以看到密钥在地图中,但根本不起作用。 输出:

--------------------------
Following keys in Map:
Keys with no null value: 301 //Key is In Map
Keys with no null value: 304
Keys with no null value: 303
Keys with no null value: 307
Searched key: 301 //same key
Result: null //result is null
Next Try: null

// UPDATE2:

我比较了两个关键文件,equals返回true,而且它们的hashcode也是一样的。但不知何故,Hibernate 使用了 Javaassist,因此不同的实例无法使用 HashMap。我认为唯一的解决方案是将 id 保存在 hashmap 中并比较它们的 id。

【问题讨论】:

  • 我正在尝试按照您所说的进行操作,但这有点困难。您是说您使用对象作为 HashMap 中的键,但是当您尝试使用应该等于 HashMap 中当前键之一的键从 HashMap 中检索值时,它返回 null?我们能否看到您正在使用的全部实体以及引用 HashMap 的代码?
  • 是的,这就是我想说的。很抱歉,由于公司法,我无法提供完整的代码:(
  • 在将键添加到 HashMap 时是否正在实例化新的键实例?我可以看看你运行测试的代码吗?

标签: java hibernate collections equals


【解决方案1】:

为了正确地利用 Object 作为 HashMap 的键,您必须正确地覆盖 hashCode() 和 equals() 方法以使其工作。您必须保证这些方法对包含相同数据的对象的不同实例给出相同的结果,才能使其正常工作。

您还必须验证您用作键的对象不会以任何方式更改,这会使 hashCode() 方法在从 HashMap 检索之前给出不同的结果。

我建议您用作键的对象是不可变的。

编辑:我正在添加一个链接,该链接解释了您在使用对象作为键时可能遇到的问题和解决方案。有很多。我建议您阅读这篇文章。

http://www.artima.com/lejava/articles/equality.html

【讨论】:

  • equals 和 hascode 已经被实现了。 (有问题添加的实现)
  • 如果您使用原始 int 作为 id,为什么不直接返回 hashCode() 的 id?
  • 可能 HashMap 不调用 hashCode() 而是调用 HashMap 特定的 hashmethode 吗?
  • 不,它先调用 equals(),然后是 hashCode()。将 id 字段设为最终字段,看看是否有帮助。这将防止值可能发生变化。
  • 我将两个关键对象与等于和哈希码的控制台输出进行了比较,它给了我真实且相同的哈希码。但这个问题的答案是:没有解决办法。 Hibernate 使用 Javassist,它操作你的 java 类,也操作你的 hashcode 和 equals 方法。问题是,我有同一个对象的两个不同实例。行不通。
猜你喜欢
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 2016-04-08
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多