BG Development


  Reply to this topicStart new topicStart Poll

> JPA, @Entity, equals(), EqualsVerifier
FidelDahan
Публикувано на: 08-05-2020, 16:36
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2421
Регистриран на: 12.06.08



Здравейте. Имате ли определена стратегия за equals() при JPA Entities?

В нов проект имат следната конвенция: Ако един клас представлява @Entity, тогава два обекта се имат за равни, ако @Id полетата им са равни. Тоест в equals() и hashCode() се сравняват само и точно полетата, които идентифицират записа в базата. Всички други полета не играят роля.

Това може би не е най-простия вариант, но звучи систематично. Един вид по този начин обектите са по-близо до тяхната репрезентация в базата и се сравняват само по primary key.

От друга страна обаче EqualsVerifier има support за JPA, но имплементира сравнението коренно различно:

By default, EqualsVerifier assumes that your entities have a business or natural key. Consequently, all fields that are marked with the @Id annotation are assumed not to participate in the class’s equals and hashCode methods. For all other fields, EqualsVerifier behaves as usual.

а в същото време дефинира горната стратегия за @NaturalId, което обаче не е от JPA, а от Hibernate:

EqualsVerifier also supports Hibernate’s @NaturalId annotation. If it detects the presence of this annotation in a class, it will assume that only the fields marked with @NaturalId participate in equals and hashCode, and that all other fields (including the ones marked with @Id) do not.

Бих искал да ползвам тази библиотека, защото е добре направена, но не разбирам защо по default игнорира @Id полетата, вместо да ги включи.

Някакви идеи?
PMEmail Poster
Top
Pascal
Публикувано на: 08-05-2020, 16:48
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 718
Регистриран на: 22.11.06



Звучи тъпо наистина. Не съм се занимавал с JPA, но много пъти съм предефинирал equals точно по описаният от теб начин (сравняващш само ключовите полета).

Аз бих направил тест преди да се доверя на това описание, защото не е ясно колко дезинфектант е изпил този който го е писал.
PMEmail Poster
Top
rosko
Публикувано на: 08-05-2020, 16:56
Quote Post



Име: Ростислав Димитров
Група: Потребител
Ранг: Редовен член

Мнения: 397
Регистриран на: 28.03.05





--------------------
When Hell is full, the dead will walk the earth
PMEmail Poster
Top
Gamma Goblin
Публикувано на: 08-05-2020, 18:06
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 3791
Регистриран на: 21.02.18



Ако не е необходимо, избягвам да имплементирам equals/hashcode. Според мен това е една от основните грешки в първоначалния дизайн на Object класа. Не всеки клас има нужда (или пък може - например e mutable вместо immutable) да бъде *ключ* в *hashCode* базирана колекция, нито пък е нужно да може да сравняваш за равенство две инстанции - за пример Random класа.


Според мен трябва да провериш как JPA третира Set/Map пропъртита на ентититата. Да не се окаже, че override-ва hashcode-a на проксито или пък проксито да не е hashcode базирано, и да се получи така че ентититата работят по един начин с нормални колекции и по друг с JPA проксирани колекции.

Това мнение е било редактирано от Gamma Goblin на 08-05-2020, 18:11


--------------------
https://ncase.me/trust-bg/
---
Misanthropy is the general hatred, dislike, distrust or contempt of the human species or human nature. A misanthrope or misanthropist is someone who holds such views or feelings.
---
INTJ’s are good at being very good at everything
---
"Чувството за вина дето искаш да ни го вмениш, може да си го навиеш на руло и да си го пъхнеш отзад." - stewe
PMEmail PosterUsers Website
Top
FidelDahan
Публикувано на: 09-05-2020, 00:47
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2421
Регистриран на: 12.06.08



Мисля, че линка на rosko обяснява ситуацията. Проблема е там, че @Id полето се задва от ДБМС, и е mutable - null преди да се персистира обекта и след това вече не е null. Ако имаме Set<Book>, след персистирането обекта ще си промени id и от там и ще си промени hashCode стойността. По този начин ще се изгуби в Set-a. Да, mutable fields не случайно не трябва да се използват в hashCode(), а от там и в еquals(). Обаче с решението което предлагат с фиксиран hashCode ще спадне значително производителността при достъп до Set (предполагам ще стане с линейно, а не константно време). Хмм.. проблема явно е не е тривиален.
PMEmail Poster
Top
ТК_
Публикувано на: 11-05-2020, 09:21
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 48
Регистриран на: 04.08.18



И в крайна сметка как реши да процедираш?
PMEmail Poster
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2019 | BG Development | All Rights Reserved
RSS 2.0