Равенство объектов / хэш-код против JPA / Равенство объектов в режиме гибернации / хэш-код

#java #hibernate #jpa #spring-data-jpa #spring-data

#java #переход в режим гибернации #jpa #spring-data-jpa #spring-данные

Вопрос:

Прочитав немного по этой теме, я немного запутался в требованиях Hibernate / JPA для равенства @Entity. Действительно ли мне нужно настраивать @EqualsAndHashCode, чтобы сделать мои объекты равными на основе уникальности БД еще в 2020 году? Тогда в чем смысл метанотации @Id?

Мне нужно иметь возможность сравнивать мои объекты на уровне объекта, поэтому пока я просто реализовал свои EqualsAndHashCode в соответствии со всеми полями, кроме @Id.

С какими именно проблемами я могу столкнуться, если буду придерживаться этого подхода? Разве в любом случае БД не выдаст исключение, если по какой-то причине Hibernate попытается сохранить или смешать 2 объекта, которые имеют одинаковый @Id, но не совпадают с моей реализацией? Действительно ли это риск? Я почти уверен, что в прошлом я видел много проектов с надлежащими тестами, и никто не определял какие-либо конкретные @EqualsAndHashCode, поэтому по умолчанию просто сравнивает экземпляры, и эти проекты прошли все виды CRUD-тестов зеленым цветом и не имели ошибок при производстве

Ответ №1:

В принципе, у вас могут возникнуть некоторые проблемы, когда у вас двунаправленные отношения между объектами. Например, если Entity1 имеет @OneToMany доступ к Entity2, а Entity2 имеет @ManyToOne доступ к EntityId, и обе эти сущности имеют @EqualsAndHashcode без указания полей (т. Е. equals И hashcode генерируются для всех полей, включая поля для отношений). В этом случае у вас будет циклическая ссылка, следовательно StackOverflow , исключение.

Чтобы избежать этого, вы можете полагаться только на поле с @Id для построения equals и hashcode (в документах hibernate есть несколько примеров такого подхода). Но в этом случае вы получите проблемы другого рода, например, если вы храните переходные объекты с автоматически сгенерированными идентификаторами в наборе (как дочерние объекты для некоторых родительских объектов), это не будет работать корректно, потому что поле id будет null в этом случае. Вероятно, вам нужно будет использовать некоторые другие поля в equals и hashcode в этом случае.

Итак, правильного ответа на этот вопрос нет. Вам нужно принимать решение каждый раз, когда вы создаете свои объекты.

Комментарии:

1. Спасибо за ответ, на данный момент я выбрал первый подход и исправил циклическую зависимость, поместив EqualsAndHashCode . Включает. и EqualsAndHashCode. Исключает, исключая объекты связи и включая пользовательские методы получения, которые учитывают только идентификатор поля локальной таблицы FK для хэша. У меня нет автоматически созданного поля, поэтому я думаю, что я играю безопасно

2. Да, я склонен делать почти то же самое в своем коде. Я хотел бы добавить, что такая же «циклическая» проблема может возникнуть и из-за @ToString аннотации Ломбока, поэтому не забудьте добавить исключения и для этой аннотации (если вы ее используете).

3. В любом случае, я не уверен, что этот ответ является полным, или мы исключаем, что это не применимо docs.jboss.org/hibernate/stable/core.old/reference/en/html /… , thorben-janssen.com /…