Es gab hier einige Diskussionen über JPA-Entitäten und welche hashCode()
/ equals()
Implementierung für JPA-Entitätsklassen verwendet werden sollte. Die meisten (wenn nicht alle) von ihnen hängen vom Ruhezustand ab, aber ich würde sie gerne neutral über die JPA-Implementierung diskutieren (ich verwende übrigens EclipseLink).
Alle möglichen Implementierungen haben ihre eigenen Vor- und Nachteile in Bezug auf:
hashCode()
/equals()
Vertrag Konformität (Unveränderlichkeit) fürList
/Set
Operationen- Ob identische Objekte (z. B. aus verschiedenen Sitzungen, dynamische Proxys aus träge geladenen Datenstrukturen) erkannt werden können
- Gibt an, ob sich Entitäten im getrennten (oder nicht persistenten) Zustand korrekt verhalten
Soweit ich sehen kann, gibt es drei Möglichkeiten :
- Überschreibe sie nicht; verlassen Sie sich auf
Object.equals()
undObject.hashCode()
hashCode()
Ichequals()
arbeite- kann keine identischen Objekte identifizieren, Probleme mit dynamischen Proxys
- Keine Probleme mit getrennten Entitäten
- Überschreiben Sie sie basierend auf dem Primärschlüssel
hashCode()
Ichequals()
bin kaputt- korrekte Identität (für alle verwalteten Entitäten)
- Probleme mit getrennten Einheiten
- Überschreiben Sie sie basierend auf der Geschäfts-ID (Nicht-Primärschlüsselfelder; was ist mit Fremdschlüsseln?)
hashCode()
Ichequals()
bin kaputt- korrekte Identität (für alle verwalteten Entitäten)
- Keine Probleme mit getrennten Entitäten
Meine Fragen sind:
- Habe ich eine Option und / oder einen Pro / Contra-Punkt verpasst?
- Welche Option haben Sie gewählt und warum?
UPDATE 1:
Mit " hashCode()
/ equals()
sind fehlerhaft" meine ich, dass aufeinanderfolgende hashCode()
Aufrufe möglicherweise unterschiedliche Werte zurückgeben, die (bei korrekter Implementierung) nicht im Sinne der Object
API-Dokumentation fehlerhaft sind, sondern Probleme beim Abrufen einer geänderten Entität aus einem Map
, verursachen. Set
oder andere Hash-basiert Collection
. Folglich funktionieren JPA-Implementierungen (zumindest EclipseLink) in einigen Fällen nicht richtig.
UPDATE 2:
Vielen Dank für Ihre Antworten - die meisten von ihnen haben eine bemerkenswerte Qualität.
Leider bin ich mir immer noch nicht sicher, welcher Ansatz für eine reale Anwendung am besten geeignet ist oder wie ich den besten Ansatz für meine Anwendung ermitteln kann. Also werde ich die Frage offen halten und auf weitere Diskussionen und / oder Meinungen hoffen.
hashcode()
derselben Objektinstanz sollte denselben Wert zurückgeben, es sei denn, in derequals()
Implementierung ändern sich. Mit anderen Worten, wenn Sie drei Felder in Ihrer Klasse haben und Ihre equals()
Methode nur zwei davon verwendet, um die Gleichheit von Instanzen zu bestimmen, können Sie erwarten, dass sich der hashcode()
Rückgabewert ändert, wenn Sie einen der Werte dieses Felds ändern - was in Anbetracht dessen sinnvoll ist dass diese Objektinstanz nicht mehr dem Wert entspricht, den die alte Instanz darstellt.