Quelle est la différence entre les associations JAP et Hibernate unidirectionnelles et bidirectionnelles?

Quelle est la différence entre les associations unidirectionnelles et bidirectionnelles?

Puisque la table générée dans la firebase database est la même, la seule différence que j’ai trouvée est que chaque côté des associations bidirectionnelles se référera à l’autre, et que l’unidirectionnel ne le sera pas.

Ceci est une association unidirectionnelle

public class User { private int id; private Ssortingng name; @ManyToOne @JoinColumn( name = "groupId") private Group group; } public class Group { private int id; private Ssortingng name; } 

L’association bidirectionnelle

 public class User { private int id; private Ssortingng name; @ManyToOne @JoinColumn( name = "groupId") private Group group; } public class Group { private int id; private Ssortingng name; @OneToMany(mappedBy="group") private List users; } 

La différence est de savoir si le groupe détient une référence de l’utilisateur.

Alors je me demande si c’est la seule différence? qui est recommandé?

La principale différence réside dans le fait que la relation bidirectionnelle fournit un access de navigation dans les deux sens, de sorte que vous pouvez accéder à l’autre côté sans requêtes explicites. Il vous permet également d’appliquer des options en cascade dans les deux sens.

Notez que l’access à la navigation n’est pas toujours bon, en particulier pour les relations «un-à-très-nombreux» et «plusieurs-à-très-nombreux». Imaginez un Group contenant des milliers d’ User :

  • Comment les accèderiez-vous? Avec autant d’ User , vous devez généralement appliquer un filtrage et / ou une pagination, de sorte que vous devez exécuter une requête de toute façon (sauf si vous utilisez le filtrage de collection , qui ressemble à un hack pour moi). Certains développeurs peuvent avoir tendance à appliquer un filtrage en mémoire dans de tels cas, ce qui n’est évidemment pas bon pour les performances. Notez qu’une telle relation peut encourager ce type de développeurs à l’utiliser sans tenir compte des implications de performance.

  • Comment appendiez-vous de nouveaux User au Group ? Heureusement, Hibernate examine le côté propriétaire de la relation lors de sa persistance, vous ne pouvez donc définir que User.group . Toutefois, si vous souhaitez conserver la cohérence des objects en mémoire, vous devez également append User à Group.users . Mais cela rendrait Hibernate à récupérer tous les éléments de Group.users de la firebase database!

Donc, je ne peux pas accepter la recommandation des meilleures pratiques . Vous devez concevoir des relations bidirectionnelles en tenant compte des cas d’utilisation (avez-vous besoin d’un access à la navigation dans les deux sens?) Et des implications possibles en termes de performances.

Voir également:

  • Dissuader les relations «ToMany» dans les modèles JPA
  • Problèmes de performances des collections Hibernate mappées

Il y a deux différences principales.

Accéder aux côtés de l’association

Le premier est lié à la manière dont vous allez accéder à la relation. Pour une association unidirectionnelle, vous pouvez naviguer dans l’association à partir d’une seule extrémité.

Ainsi, pour une association @ManyToOne unidirectionnelle, cela signifie que vous ne pouvez accéder à la relation que du côté enfant où réside la clé étrangère.

Si vous avez une association unidirectionnelle @OneToMany , cela signifie que vous ne pouvez accéder à la relation que du côté parent où réside la clé étrangère.

Pour l’association bidirectionnelle @OneToMany , vous pouvez naviguer dans l’association dans les deux sens, du côté parent ou du côté enfant.

Vous devez également utiliser des méthodes d’utilitaire d’ajout / suppression pour les associations bidirectionnelles afin de vous assurer que les deux côtés sont correctement synchronisés .

Performance

Le deuxième aspect est lié à la performance.

  1. Pour @OneToMany , les associations unidirectionnelles ne sont pas aussi performantes que celles bidirectionnelles .
  2. Pour @OneToOne , une association bidirectionnelle amènera le parent à aller chercher si Hibernate ne peut pas dire si le proxy doit être assigné ou une valeur nulle .
  3. Pour @ManyToMany , le type de collection fait toute la différence, car les Sets fonctionnent mieux que les Lists .

En termes de codage, une relation bidirectionnelle est plus complexe à mettre en œuvre car l’application est responsable de la synchronisation des deux côtés conformément à la spécification JPA 5 (à la page 42). Malheureusement, l’exemple donné dans la spécification ne donne pas plus de détails et ne donne donc pas une idée du niveau de complexité.

Lorsque vous n’utilisez pas de cache de deuxième niveau, il n’est généralement pas difficile de ne pas implémenter correctement les méthodes de relation car les instances sont supprimées à la fin de la transaction.

Lorsque vous utilisez un cache de second niveau, si quelque chose est corrompu à cause de méthodes de gestion des relations implémentées de manière incorrecte, cela signifie que les autres transactions verront également les éléments corrompus (le cache de second niveau est global).

Une relation bidirectionnelle correctement implémentée peut simplifier les requêtes et le code, mais ne devrait pas être utilisé si cela n’a pas vraiment de sens en termes de logique métier.

Je ne suis pas sûr à 100% que c’est la seule différence, mais c’est la principale différence. Il est également recommandé d’avoir des associations bidirectionnelles par les documents Hibernate:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/best-practices.html

Plus précisément:

Préférer les associations bidirectionnelles: les associations unidirectionnelles sont plus difficiles à interroger. Dans une grande application, presque toutes les associations doivent être navigables dans les deux sens dans les requêtes.

J’ai personnellement un léger problème avec cette recommandation générale – il me semble qu’il y a des cas où un enfant n’a aucune raison pratique de connaître son parent (par exemple, pourquoi un article de commande doit-il connaître l’ordre dans lequel il est?). associé à?), mais je vois une valeur dans une partie raisonnable du temps aussi. Et comme la bidirectionnalité ne fait vraiment pas de mal, je ne trouve pas trop choquant d’adhérer.