2010-10-20 4 views
7

J'ai une question qui je pense devrait être assez commune mais je ne trouve pas de réponse.hibernate @ManyToMany bidirectionnel désireux aller chercher

J'ai 2 objets: Groupe et utilisateur. Mes cours ressemblent à ceci:

class Group 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<User> users; 
} 

class User 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Maintenant, lorsque je tente d'obtenir un utilisateur de la base de données, il apporte tous ses groupes et tous les groupes apporter tous ses utilisateurs et ainsi de suite. Enfin, j'obtiens une exception stackoverflow. Comment puis-je résoudre ce problème tout en conservant mon association bidirectionnelle et la possibilité d'atteindre les objets dans les listes?

Répondre

8

Avez-vous le même problème si vous faites l'un des côtés de votre assocation bi-directionnel du possédant côté de l'association en utilisant l'attribut mappedBy (que vous devez utiliser de toute façon)? Comme ceci:

@Entity public class Group { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups") 
    List<User> users; 
} 

@Entity public class User { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

Mise à jour: Je ne trouve aucune preuve que l'utilisation EAGER aller chercher sur les deux côtés d'une association bidirectionnelle est interdite et autant que je sache, il n'y a aucune mention d'une telle restriction dans la documentation Hibernate et/ou la spécification JPA.

En fait, selon la this comment de Emmanuel Bernard à un (en quelque sorte similaire) Volume:

LAZY ou EAGER doit être orthogonal à un problème de boucle infinie dans le code de base. Mise en veille prolongée sait comment gérer les graphiques cycliques

Pour moi, ce qui précède est assez clair, Hibernate doit être capable de gérer votre cartographie (comme je l'ai mentionné dans un commentaire) et je serais tenté de considérer tout comportement contradictoire comme punaise.

Si vous pouvez fournir un cas de test permettant de reproduire le problème, je vous suggère d'ouvrir un problème.

+0

oui. la même chose arrive. Je peux comprendre que cela a du sens b/c hibernate doit amener tous les objets listés pour chaque liste et c'est une boucle infinie. Ma question est de savoir s'il est possible de limiter la profondeur qu'Hibernate apporte aux objets (quelque chose comme fetch_max_depth mais pour many-to-many). – refaelos

+0

@Rafa En fait, je m'attendrais à ce qu'Hibernate détecte le cycle et fasse le bon choix (mais je n'ai pas pris le temps de le tester). D'autre part, je ne peux pas dire que ce chargement avec impatience les deux côtés d'un plusieurs-à-plusieurs ressemble à une bonne idée. –

0

Hibernate fonctionne correctement lorsqu'il essaie d'aller chercher tout ce dont il a besoin. La modélisation des objets doit prendre en compte Hibernate afin que les boucles et les exceptions stackoverflow ne se produisent pas.

Ce que j'ai fait est de supprimer un côté de la relation. Vous pouvez décider si vous voulez supprimer ce côté ou le quitter et définir l'autre côté en tant que propriétaire. Vous aurez également besoin d'enlever la recherche ardente de ce côté.

Ce serait bien si Hibernate pouvait donner un mécanisme pour définir la profondeur de récupération dans les relations plusieurs-à-plusieurs.

0

Vous pouvez définir la propriété "hibernate.max_fetch_depth" sur quelque chose comme 3 pour limiter la récupération désirée.

Questions connexes