Hibernate chercher rejoignez -> ne peut pas extraire plusieurs sacs
Problème est que j'ai deux sacs dans mon entité qui je voudrais afficher dans mon jsf frontend (du Printemps à l'arrière donc pas de lazy loading). Je dois donc avec impatience les récupérer pour afficher les informations dans une liste comme ceci:
- Point 1 (Étiquette 1, Étiquette 2) (Tag1 ... Balise n)
- Point 2 (Label 3, 4) (Tag1 ... Balise n)
Mettant les deux Listes à la hâte n'a pas fonctionné. J'ai donc tenté ma chance avec une extraction rejoindre. Il m'a permis de récupérer une liste, mais quand j'ai ajouté la deuxième liste, je reçois le connu "impossible d'extraire plusieurs sacs d'erreur".
Peuvent Hiberner gérer deux fetch rejoint dans une requête?
public class PointOfInterest
@OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();
@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();
Mon fetch rejoindre:
SELECT DISTINCT p from PointOfInterest p
left join fetch p.labels
left join fetch p.tags WHERE p.figure = :figure
Sur le démarrage de la création de mon hibernation usine échoue avec:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
... 55 more
OriginalL'auteur mkuff | 2011-08-24
Vous devez vous connecter pour publier un commentaire.
La réponse est: non. Il ne peut pas gérer. C'est ce qu'il dit.
Pour les types de valeur (composite-element) ça ne marche même pas, parce que vous n'obtenez pas l'information de ce qui appartient en réalité à la même sac d'élément.
Habituellement, il n'a même pas de sens. Si vous interrogez une table et bénéficiez de 10 enregistrements dans la table de départ, 10 dans le premier sac et un autre de 10 dans le deuxième sac, vous allez récupérer 1000 lignes, juste pour créer ces 30 objets en mémoire. Imaginez le nombre de dossiers quand il y aurait de 100 enregistrements dans chaque tableau (indice: de 1 000 000 au lieu de 300) et lorsque vous chercher rejoindre un autre sac (indice: 100,000,000 au lieu de 400) ...
Par la route: join fetch peut conduire à des effets bizarres et des problèmes et doit être évitée, sauf si vous savez exactement ce que vous faites.
Vous pouvez éteindre le chargement paresseux, ce qui est mauvais pour la performance. Ceci récupère les sacs immédiatement par requêtes distinctes. Vous pouvez également accéder à la sacs (eg. taille) pour forcer le chargement. La meilleure solution est de créer de la session à l'extérieur de la dao et de les conserver pour l'ensemble de l'opération commerciale. (Création d'une session à chaque appel de la dao est appelée session-par appel et est un anti-modèle.)
Donc c'est vraiment un catch 22 problème: si vous n'utilisez pas de join fetch, vous obtenez n+1 problème ou l'initialisation tardive exception. Session hors dao est un hack, tout d'abord parce qu'il est nulle part près de l'APC de contrat et le deuxième de tous, car il est difficilement contrôlable, car vous ne devriez pas faire d'hypothèses sur la durée de vie d'une entité au moment où vous l'avez créée. Il peut s'étaler sur plusieurs demandes, pas nécessairement http.
Vous pouvez éviter de N+1 avec le grand chargement par lot, c'est d'être transparent et ne pas avoir d'effets secondaires. Vous n'avez pas besoin de faire référence à la session de l'extérieur de la dal, mais vous devez contrôler la durée de vie de la transaction à partir de l'extérieur de la dal, parce que c'est plus long qu'un seul appel à la db. Vous pouvez vous cacher derrière un dal de l'interface. Dans notre projet, nous avons mis en place un environnement de transaction chose, qui est stocké dans un thread champ statique dans la dal.
OriginalL'auteur Stefan Steinegger
Au lieu de l'aide de Jeu, vous pouvez diviser la requête et de charger les entités dans les différentes requêtes.
Par exemple
Veuillez vous référer le lien
OriginalL'auteur Manu
Vous ne pouvez pas avoir 2
1-n
hâte-joint (ou HQL fetch-joint) dans la même requête.Si vous vous joignez à un
1-n
table et il y a 10 lignes correspond, toutes les colonnes sur la non-N entités sont dupliquées pour chaque ligne.Si elle renvoie de 10 lignes, il aurait à décider de qui 1-n causé les lignes supplémentaires. Ce qui, techniquement, il pourrait basée sur la jointure des clés - si la jointure clés sont uniques clés primaires. Mais cette exception indique qu'hibernate ne peut pas dire.
OriginalL'auteur Curtis Yallop