2012-07-12 7 views
7

Znajduję wiele postów, gdzie wyjaśniono, że zawsze należy przesłonić Equals/GetHashCode na klasę encji NHibernate. Jeśli nie używam zestawów, czy to naprawdę konieczne?Czy istnieje przykład, dlaczego Equals/GetHashCode powinny być nadpisywane w NHibernate?

Po prostu nie mogę znaleźć próbki, w której pokazane jest, że brakujące wartości równe/GetHashCode mogą prowadzić do nieoczekiwanego i niewłaściwego zachowania. Wszystko wydaje się działać bez nich doskonale. To naprawdę dziwne, że wszyscy mówią, że jest to konieczne, ale nikt nie może dostarczyć próbki, która pokazuje, że jest to konieczne.

Odpowiedz

11

Na urządzeniu SO był ostatnio napisany komunikat o operacji NHibernate, wybierając opcję N + 1, nawet jeśli podano fetch. Problem was z brakującą implementacją Equals/GetHashCode.

Odpowiedź łączy się z innym podobnym question.

Oto another question w sprawie uzasadnień dotyczących nadpisań Equals/GetHashCode.

Nhibernate n+1 with ternary relationship. Want the middle entity in the ternary
Nhibernate producing proxy despite HQL fetch
NHibernate: Reasons for overriding Equals and GetHashCode
Why Equals and GetHashCode are so important to NHibernate
Why is it important to override GetHashCode when Equals method is overridden?


Edit

Nie trzeba zastąpić je przez cały czas. Może to być konieczne, jeśli używasz kluczy złożonych, wielu sesji z odłączonymi jednostkami lub sesji bezstanowych.

Jeśli pracujesz tylko z jedną sesją, NHibernate przechowuje obiekty do pamięci podręcznej pierwszego poziomu za pomocą mapy tożsamości. Porównanie jednostek w tym przypadku odbywa się poprzez porównywanie identyfikatorów.

W powyższych przypadkach (odłączony podmiot, sesja bezstanowa) NHibernate porównuje rzeczywiste elementy, a nie ich identyfikatory. Domyślnie Object.Equals odnosi się do równości. Zatem dwa obiekty są równe, jeśli wskazują na to samo wystąpienie. Możesz mieć dwie instancje o tej samej tożsamości, ale Object.Equals zwróci im false. Jest to w przeciwieństwie do Entitydefinition:

obiektu, który nie jest definiowany przez jego cech, lecz poprzez gwint ciągłości i tożsamości.

JBoss Hibernate wiki ma a good explanation na Equals i HashCode z nielicznych przykładów kodu.

+0

Wydaje się, że dotyczy to tylko kluczy kompozytowych. Nie używamy ich. Czy jest to jedyny przypadek, w którym potrzebne jest Equals/GetHashCOde? Znam trzy ostatnie linki, które łączyłeś. Nie widzę tam żadnych próbek kodu, które odtwarzają złe zachowanie. – Antineutrino

+0

Identyfikatory złożone to jeden przypadek. Zaktualizowałem swoją odpowiedź z tekstem i linkiem do strony wiki Hibernate ... –

+0

+1 imponujący zbiór linków. –

4

W rzeczywistości są tylko rzadkie przypadki, gdy prowadzi do skutków ubocznych. Ale jeśli je zdobędziesz, są dość subtelne. Oprócz złożonych kluczy podstawowych i kluczy słownika, które zawsze wymagają poprawnej implementacji Equals/GetHashCode.

NH dba o tworzenie instancji tylko raz w pamięci, więc domyślne porównanie porównania powinno zadziałać ... , jeśli nie byłoby leniwego ładowania.

Gdy nie zastępujesz Equals, masz problemy podczas pracy z serwerami proxy. Zawsze są dwa wystąpienia: proxy i rzeczywisty podmiot. Obaj reprezentują ten sam byt. Tylko przy poprawnie wdrożonej metodzie równości traktowane jest to samo.

+0

OK, więc oznacza to, że jeśli nie używam kluczy złożonych lub słowników, jedynym powodem jest to, że użycie podmiotu i jego proxy jest przejrzyste. – Antineutrino

+0

Jedyny powód, o którym wiem. Nie wdrożyliśmy Equals/GetHashCode w naszym projekcie i nie napotkaliśmy żadnych problemów, dopóki nie zaczęliśmy używać leniwego ładowania. –

+0

Dodałem przykład do [tego posta] (http://stackoverflow.com/a/5857854/200322), który pokazuje, w jaki sposób równość może zakończyć się niepowodzeniem. Jeśli masz obiekt, który jest porównywany z kolekcją leniwych ładunków, zaczniesz porównywać proxy z rzeczywistą jednostką (a domyślna równość odniesienia zawiedzie!). IMO, nie powinno być "rób tego tylko w tych skrajnych przypadkach", powinieneś zawsze robić to, aby uratować swoje zdrowie psychiczne podczas debugowania tych problemów. – TheCloudlessSky