2009-05-27 6 views
3

Dans le cas suivant:Hibernate/JPA Parent-Child - est-il acceptable pour Parent equals()/hashCode() d'utiliser l'identifiant DB?

@Entity 
public class Parent implements Serializable { 
    @Id 
    private Long id; 
    // mapped ManyToOne below... 
    private List<Child> children = new ArrayList<Child>(); 

    ... 

} 

Est-ce une mauvaise pratique d'avoir Parent.equals() et Parent.hashCode() utilisent seulement id? Je comprends que Child.equals() et Child.hashCode() doivent utiliser un ensemble immuable d'attributs pour une "clé naturelle" pour qu'ils soient correctement gérés par Parent. Cependant, si Parent est toujours un objet de premier niveau (c.-à-d. Que ce n'est jamais le côté inverse d'une association), y a-t-il quelque chose de mal à utiliser uniquement l'identifiant?

Y at-il des effets indésirables qui pourraient se manifester en faisant cela? Je devine que peut-être si je fais cela, que lorsque j'ajoute un enfant (ou supprimer), Hibernate ne sera pas capable de dire que Parent a changé (et doit être mis à jour dans DB)? Dans ce cas, dois-je utiliser la propriété children pour Parent.equals() et Parent.hashCode()?

Je demande parce que la mise en veille prolongée docs explicity dire de ne pas utiliser la propriété @Id pour une « clé naturelle » ...

Répondre

5

Le principal problème avec l'aide d'ID comme égaux et hashCode base est des objets unpersisted. Ces objets commencent vraisemblablement tous par le même ID et cela ne peut pas être comparé correctement pour l'égalité. Même si vous ne placez jamais les objets dans une collection, s'ils sont exposés via une API et que quelqu'un d'autre peut en créer une instance et les mettre dans une collection, vous vous êtes ouvert à de vilains bugs.

+0

Je comprends ce que vous dites, mais techniquement, si id est zéro, alors ils sont vraiment égaux: ils sont tous les deux des objets Parent non-persistants. Pour mon exemple ci-dessus avec seulement ces deux propriétés (id et enfants), comment suggéreriez-vous l'implémentation de equals() et hashCode()? Aurais-je besoin d'introduire plus de propriétés? – GreenieMeanie

+0

Même s'il n'y a pas d'Hibernate impliqué, pouvez-vous autoriser des mutateurs sur les champs utilisés pour equals() et hashCode()? Quelqu'un pourrait mettre une instance dans un HashSet, changer un champ qui affecte le code de hachage, et ainsi casser l'ensemble. Mais interdire cela semble un peu dur. Je penche pour que vous devez considérer chaque cas séparément et peser les avantages et les inconvénients les uns contre les autres ... – waxwing

+1

@ Greenie: Si j'importe des données d'une autre source, je pourrais créer un graphique complet de nouveaux objets que j'ai stocker quelque part avant de les persister et de chasser hiberner. Juste parce qu'ils ont l'ID 0 ne signifie pas qu'ils sont égaux, cela signifie qu'ils n'ont pas d'ID, mais c'est tout. – Jherico

Questions connexes