Гибернация: когда необходимо реализовать equals () и hashCode (), и если да, то как?

Основываясь на различных неудачных опытах , мое практическое правило как программиста на Java состоит в том, чтобы реализовывать equals () и hashCode () только для неизменяемых объекты, где два экземпляра объекта действительно взаимозаменяемы.

В основном я хочу избежать ситуаций, подобных ключевой проблеме HashMap в этой ссылке, или подобных следующей:

  1. Получить вещь с определенной идентичностью.
  2. Измените это.
  3. Добавить в набор.
  4. (позже) Получите другую вещь с тем же именем.
  5. Измените это.
  6. Добавить в тот же набор.
  7. Не заметить, что этого добавления на самом деле не происходит, поскольку набор думает, что вещь уже существует.
  8. Сделайте что-нибудь с вещами в наборе.
  9. Невозможно заметить, что изменение с шага (5) игнорируется, и у нас все еще есть состояние с шага (2).

И, по большому счету, в течение моей карьеры в Java я не нашел большого применения для equals () , за исключением для (1) объектов значений и (2) складывать вещи в коллекции. Я также обнаружил, что неизменяемость + копирование и изменение конструкторов / построителей, как правило, намного более счастливый мир, чем сеттеры.Два объекта могут иметь одинаковый идентификатор и могут представлять одну и ту же логическую сущность, но если у них разные данные - если они представляют собой снимки концептуальной сущности в разное время - тогда они не equal () .

Так или иначе, я сейчас нахожусь в магазине Hibernate, и мои более опытные коллеги говорят мне, что этот подход не сработает. В частности, похоже, что в следующем сценарии -

  1. Hibernate загружает что-то из базы данных - мы назовем это instance h1 .
  2. Эта вещь упорядочивается и отправляется куда-то через веб-службу.
  3. Клиент веб-службы возится с ним и отправляет обратно измененную версию.
  4. Измененная версия неупорядочивается на сервере - мы назовем ее instance h4 .
  5. Мы хотим, чтобы Hibernate обновлял базу данных с изменениями.

- кроме h1.equals (h4) (или, возможно, h4.equals (h1) , я не понимаю, но я надеюсь, что это транзитивно в любом случае, да что угодно) , Hibernate не сможет сказать, что это одно и то же, и Bad Things Will Happen.

Итак, что я хочу знать:

  • Это правда?
  • Если да, то почему? Для чего Hibernate использует equals () для?
  • Если Hibernate требует, чтобы h1 и h4 были равны, как он (и как мы) сохраняем отслеживать, какая из них является измененной версией?

Примечание: Я прочитал Реализация equals () и hashCode () в документации Hibernate, и это не касается ситуации, в которой я ' m беспокоит, по крайней мере напрямую, и не объясняет подробно, что действительно нужно Hibernate из equals () и hashCode () . Также нет ответа на и хэш-код в Hibernate , иначе я бы не стал публиковать это.

7
задан Community 23 May 2017 в 11:56
поделиться