Odbyło się tutaj kilka dyskusji na temat jednostek JPA i tego, które hashCode()
/ equals()
implementację należy zastosować dla klas jednostek JPA. Większość (jeśli nie wszystkie) z nich zależy od Hibernacji, ale chciałbym omówić je neutralnie z implementacją JPA (nawiasem mówiąc, używam EclipseLink).
Wszystkie możliwe wdrożenia mają swoje zalety i wady dotyczące:
hashCode()
/equals()
zgodność kontraktu (niezmienność) dlaList
/Set
operacji- Czy można wykryć identyczne obiekty (np. Z różnych sesji, dynamiczne proxy z leniwie załadowanych struktur danych)
- Czy jednostki zachowują się poprawnie w stanie odłączonym (lub nietrwałym)
Jak widzę, istnieją trzy opcje :
- Nie zastępuj ich; polegać na
Object.equals()
iObject.hashCode()
hashCode()
/equals()
praca- nie można zidentyfikować identycznych obiektów, problemy z dynamicznymi serwerami proxy
- żadnych problemów z odłączonymi jednostkami
- Zastąp je na podstawie klucza podstawowego
hashCode()
/equals()
są zepsute- poprawna tożsamość (dla wszystkich zarządzanych podmiotów)
- problemy z odłączonymi jednostkami
- Zastąp je na podstawie identyfikatora firmy (pola klucza innego niż podstawowy; co z kluczami obcymi?)
hashCode()
/equals()
są zepsute- poprawna tożsamość (dla wszystkich zarządzanych podmiotów)
- żadnych problemów z odłączonymi jednostkami
Moje pytania to:
- Czy przegapiłem opcję i / lub punkt pro / con?
- Którą opcję wybrałeś i dlaczego?
AKTUALIZACJA 1:
Przez „ hashCode()
/ equals()
są łamane”, to znaczy, że kolejne hashCode()
wywołania mogą zwracać różne wartości, co jest (gdy prawidłowo wdrożone) nie uszkodzony w sensie Object
dokumentacji API, ale co powoduje problemy, gdy próbuje odebrać zmieniony podmiot od A Map
, Set
lub inne oparty na haszowaniu Collection
. W związku z tym implementacje JPA (przynajmniej EclipseLink) nie będą działać poprawnie w niektórych przypadkach.
AKTUALIZACJA 2:
Dziękujemy za odpowiedzi - większość z nich ma niezwykłą jakość.
Niestety nadal nie jestem pewien, które podejście będzie najlepsze dla aplikacji z prawdziwego życia, ani jak określić najlepsze podejście dla mojej aplikacji. Będę więc pozostawił pytanie otwarte i mam nadzieję na dalsze dyskusje i / lub opinie.
hashcode()
coś przeciwnego - wywołanie tej samej instancji obiektu powinno zwrócić tę samą wartość, chyba że equals()
zmienione zostaną pola użyte w implementacji. Innymi słowy, jeśli masz trzy pola w swojej klasie, a twoja equals()
metoda używa tylko dwóch z nich do ustalenia równości instancji, możesz spodziewać hashcode()
się zmiany wartości zwracanej, jeśli zmienisz jedną z tych wartości pola - co ma sens, jeśli weźmiesz pod uwagę że ta instancja obiektu nie jest już „równa” wartości reprezentowanej przez starą instancję.