JPA的hashCode()/ equals()两难 [英] The JPA hashCode() / equals() dilemma

查看:240
本文介绍了JPA的hashCode()/ equals()两难的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一些 讨论关于JPA实体和哪些<$ c $应该为JPA实体类使用c> hashCode() / equals()实现。大多数(如果不是全部的话)都依赖于Hibernate,但我想讨论它们JPA-implementation-neutrally(顺便说一句,我使用EclipseLink)。

所有可能的实现都有自己的优势劣势


  • hashCode() / equals() 合约符合列表 / 设置操作

  • 是否相同<可以检测强对象(例如来自不同会话,来自懒惰加载的数据结构的动态代理)
  • 实体是否在分离(或非持久)状态下正确运行
  • strong>




据我所见,有三个选项


  1. 不要重写它们;依赖于 Object.equals() Object.hashCode()


    • hashCode() / equals() work

    • 无法识别相同的对象,动态代理的问题

    • 没有分离实体的问题

  2. 根据主键覆盖它们。

    $ ul $ b $ liq $ hashCode() / equals()被破坏
  3. 正确的身份(针对所有托管实体)分离的实体


  4. 根据 Business-Id 覆盖它们(非主键字段;外键?)


    • hashCode() / equals() code>已损坏

    • 正确的身份(对于所有托管实体)
    • 分离的实体没有问题

      1. 我有没有想念一个选项和/或亲/点?


      2. 您选择什么选项以及为什么?




      $ b 更新1:通过 hashCode() / equals()被破坏,我的意思是连续的 hashCode() invocations可能从 Object API文档的意义上返回不同的值,这是(正确实现时)没有被破坏的,但是当试图从 Map Set 或其他基于散列的集合。因此,在某些情况下,JPA实现(至少EclipseLink)无法正常工作。



      更新2:



      感谢您的答复 - 其中大部分都具有卓越的品质。

      不幸的是,我仍然不确定哪种方法最适合现实生活中的应用程序,或者如何确定我的应用程序的最佳方法。所以,我会保持这个问题的公开性,希望能有更多的讨论和/或意见。 解决方案

阅读这篇非常不错的文章关于这个问题:不要让Hibernate窃取你的身份



文章的结论如下所示:



对象被持久化到数据库时,对象标识难以正确实现。但是,这些问题完全来自于允许对象在保存
之前没有ID而存在。我们可以通过承担
的责任,将对象ID从对象关系映射框架
(如Hibernate)中分离出来,从而解决这些问题。相反,一旦
对象被实例化,对象ID就可以被分配。这使得对象标识变得简单并且
没有错误,并且减少了域模型中需要的代码量。


There have been some discussions here about JPA entities and which hashCode()/equals() implementation should be used for JPA entity classes. Most (if not all) of them depend on Hibernate, but I'd like to discuss them JPA-implementation-neutrally (I am using EclipseLink, by the way).

All possible implementations are having their own advantages and disadvantages regarding:

  • hashCode()/equals() contract conformity (immutability) for List/Set operations
  • Whether identical objects (e.g. from different sessions, dynamic proxies from lazily-loaded data structures) can be detected
  • Whether entities behave correctly in detached (or non-persisted) state

As far I can see, there are three options:

  1. Do not override them; rely on Object.equals() and Object.hashCode()
    • hashCode()/equals() work
    • cannot identify identical objects, problems with dynamic proxies
    • no problems with detached entities
  2. Override them, based on the primary key
    • hashCode()/equals() are broken
    • correct identity (for all managed entities)
    • problems with detached entities
  3. Override them, based on the Business-Id (non-primary key fields; what about foreign keys?)
    • hashCode()/equals() are broken
    • correct identity (for all managed entities)
    • no problems with detached entities

My questions are:

  1. Did I miss an option and/or pro/con point?
  2. What option did you choose and why?



UPDATE 1:

By "hashCode()/equals() are broken", I mean that successive hashCode() invocations may return differing values, which is (when correctly implemented) not broken in the sense of the Object API documentation, but which causes problems when trying to retrieve a changed entity from a Map, Set or other hash-based Collection. Consequently, JPA implementations (at least EclipseLink) will not work correctly in some cases.

UPDATE 2:

Thank you for your answers -- most of them have remarkable quality.
Unfortunately, I am still unsure which approach will be the best for a real-life application, or how to determine the best approach for my application. So, I'll keep the question open and hope for some more discussions and/or opinions.

解决方案

Read this very nice article on the subject: Don't Let Hibernate Steal Your Identity.

The conclusion of the article goes like this:

Object identity is deceptively hard to implement correctly when objects are persisted to a database. However, the problems stem entirely from allowing objects to exist without an id before they are saved. We can solve these problems by taking the responsibility of assigning object IDs away from object-relational mapping frameworks such as Hibernate. Instead, object IDs can be assigned as soon as the object is instantiated. This makes object identity simple and error-free, and reduces the amount of code needed in the domain model.

这篇关于JPA的hashCode()/ equals()两难的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆