Il y a eu quelques discussions ici sur les entités JPA et qui hashCode()
/equals()
implémentation à utiliser pour les classes d'entités JPA. La plupart (sinon la totalité) d'entre eux dépendent d'Hibernate, mais j'aimerais en discuter de manière neutre sur l'implémentation JPA (j'utilise EclipseLink, soit dit en passant).
Toutes les implémentations possibles ont leurs propres avantages et inconvénients concernant:
hashCode()
/equals()
conformité du contrat (immuabilité) pourList
/Set
opérations- Qu'ils soient identiques objets (par exemple de sessions différentes, des proxys dynamiques provenant de structures de données chargées paresseusement) peuvent être détectés
- Si les entités se comportent correctement dans un état détaché (ou non persistant)
Pour autant que je puisse voir, il y a trois options :
- Ne les remplacez pas; compter sur
Object.equals()
etObject.hashCode()
hashCode()
/equals()
travail- impossible d'identifier des objets identiques, problèmes avec les proxys dynamiques
- aucun problème avec les entités détachées
- Remplacez-les, en fonction de la clé primaire
hashCode()
/equals()
sont cassés- identité correcte (pour toutes les entités gérées)
- problèmes avec des entités détachées
- Remplacez-les, en fonction de l' ID d'entreprise (champs de clé non primaire; qu'en est-il des clés étrangères?)
hashCode()
/equals()
sont cassés- identité correcte (pour toutes les entités gérées)
- aucun problème avec les entités détachées
Mes questions sont:
- Ai-je raté une option et / ou un point pro / con?
- Quelle option avez-vous choisie et pourquoi?
MISE À JOUR 1:
Par " hashCode()
/ equals()
sont rompus", je veux dire que des hashCode()
invocations successives peuvent renvoyer des valeurs différentes, ce qui (lorsqu'elles sont correctement implémentées) n'est pas rompu au sens de la Object
documentation de l' API, mais qui provoque des problèmes lors de la tentative de récupération d'une entité modifiée à partir d'un Map
, Set
ou autre basé sur le hachage Collection
. Par conséquent, les implémentations JPA (au moins EclipseLink) ne fonctionneront pas correctement dans certains cas.
MISE À JOUR 2:
Merci pour vos réponses - la plupart ont une qualité remarquable.
Malheureusement, je ne sais toujours pas quelle approche sera la meilleure pour une application réelle, ou comment déterminer la meilleure approche pour mon application. Donc, je garderai la question ouverte et j'espère avoir d'autres discussions et / ou opinions.
hashcode()
à la même instance d'objet devrait retourner la même valeur, à moins que les champs utilisés dans la equals()
mise en œuvre ne changent. En d'autres termes, si vous avez trois champs dans votre classe et que votre equals()
méthode n'en utilise que deux pour déterminer l'égalité des instances, vous pouvez vous attendre à ce que la hashcode()
valeur de retour change si vous modifiez l'une de ces valeurs de champ - ce qui est logique lorsque vous considérez que cette instance d'objet n'est plus "égale" à la valeur que l'ancienne instance représentait.