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/Setoperacji- 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 Objectdokumentacji API, ale co powoduje problemy, gdy próbuje odebrać zmieniony podmiot od A Map, Setlub 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ę.
