#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 /…