IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Trop de requète.. Chargement intelligent (Collection Map, set bag)


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 73
    Points : 66
    Points
    66
    Par défaut Trop de requète.. Chargement intelligent (Collection Map, set bag)
    Bonjours,

    J'ai deux table lié 1-N
    J'effectue un select * sur la première
    puis un select sur la deuxième avec un where in du premier résultat.

    Ensuite le fait un get"Collection" sur chaque enregistrement du premier résultat et je constate que pour ceci il fait plain de requète...or normalement apres mes deux première requètes tous les enregistrement devrai être déjà en mémoire....

    Où est l'erreur??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    s = "from InfHostingSite ";
    		query = session.createQuery(s);
    		List sites = query.list();
     
    		printList(sites);
     
    		s = "from InfPlatform p where p.InfHostingSite in (:sites)";
    		//query = session.createQuery(s).setParameter("sites", sites); 
    		query = session.createQuery(s).setParameterList("sites", sites);
     
    		List platforms2 = query.list();
    		Iterator iter2 = platforms2.iterator();
     
    		String s2="";
    		while ( iter2.hasNext() ) {
    		    InfPlatform pl = (InfPlatform) iter2.next();
    		    s2+= pl.getPath()+"\n";
    		}
    		System.out.println(s2);
    		//*/
     
    		iter2 = sites.iterator();
    		s2="";
    		while ( iter2.hasNext() ) {
    			InfHostingSite s1 = (InfHostingSite) iter2.next();
    			Set<InfPlatform> sp = s1.getInfPlatforms();
    			Iterator it = sp.iterator();
    			while (it.hasNext()) {
    				InfPlatform p = (InfPlatform) it.next();
    				s2 += p.getPath()+"\n";
    			}
    		}
    		System.out.println(s2);
    Merci

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Si tu parles de ton itération sur "sites", c'est normal.
    Par défaut, tu es en lazy loading, donc quand tu récupères tes sites, les collections associées ne sont pas chargées.
    Voilà pourquoi quand tu itères, Hibernate effectue des requêtes pour les charger.
    Si tu veux éviter ça, tu peux utiliser un left join fetch un peu de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    from InfHostingSite site left join fetch site.infPlatforms

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 73
    Points : 66
    Points
    66
    Par défaut
    Merci.
    Oui je parlai bien de mon iteration sur site. Tu as raison les collection n'était pas chargé. Chaque entité Platform oui mais les association Site->Platforms n'était pas initialisé.

    Intéressant le LEFT JOIN en effet.
    Par contre ma requête doit s'effectuer dans l'autre sens. le from se fait sur Site et le join sur Platforms.

    ce qui donne en effet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    	s = "from InfHostingSite ";
    	query = session.createQuery(s);
    	List sites = query.list();
    	s = "from InfHostingSite site left join fetch site.InfPlatforms where site in (:sites)"; 
    	query = session.createQuery(s).setParameterList("sites", sites);
    	query.list();
     
    	Iterator iter3 = sites.iterator();
    	String s3="";
    	while ( iter3.hasNext() ) {
    		InfHostingSite s1 = (InfHostingSite) iter3.next();
    		Set<InfPlatform> sp = s1.getInfPlatforms();
    		Iterator it = sp.iterator();
    		while (it.hasNext()) {
    			InfPlatform p = (InfPlatform) it.next();
    			s3 += p.getPath()+"\n";
    		}
    	}
    		System.out.println(s3);
    Et en regardant les log de la base de donné:
    Il n'y a que deux requête effectué: qui correspond en gros (j'ai mis des étoiles pour que ce soit plus lisible)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    LOG:  duration: 0.484 ms  statement: EXECUTE <unnamed>  [PREPARE:
     select infhosting0_.* from "INF_HostingSite" infhosting0_]
    LOG:  duration: 4.353 ms  statement: EXECUTE <unnamed>  [PREPARE:  
    select infhosting0_.* , infplatfor1_.* 
    from "INF_HostingSite" infhosting0_ 
    left outer join "INF_Platform" infplatfor1_ on infhosting0_."vs_objectUID"=infplatfor1_."inf_hostingSiteUID" 
    where infhosting0_."vs_objectUID" in ($1 , $2 , $3 , $4 , $5 , $6 , $7 , $8 , $9 , $10 , $11 , $12 , $13 , $14 , $15 , $16 , $17)]
    Ca c'est bon!

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 73
    Points : 66
    Points
    66
    Par défaut
    Encore une petite question.
    La requête suivante ne passe pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    s = "SELECT InfHostingSite  from InfHostingSite site left join fetch site.InfPlatforms where site in (:sites)";
    Le fait de mettre SELECT InfHostingSite fait planté. Pourquoi?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    12:21:58,560 DEBUG FromReferenceNode:51 - Resolved :  site -> infhosting0_."vs_objectUID"
    12:21:58,560 DEBUG HqlSqlBaseWalker:117 - select : finishing up [level=1, statement=select]
    12:21:58,560 DEBUG HqlSqlWalker:509 - processQuery() :  ( SELECT ( {select clause} null ) ( FromClause{level=1} ( "INF_HostingSite" infhosting0_ "INF_Platform" infplatfor1_ ) ) ( where ( in infhosting0_."vs_objectUID" ( inList ? ) ) ) )
     
    	at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281)
    	at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229)
    	at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:228)
    	at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:160)
    	at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
    	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
    	at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
    	at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
    	at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
    	at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
    	at test.test.Test1.testInstance(Test1.java:126)
    	at test.test.Test1.main(Test1.java:64)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    73
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 73
    Points : 66
    Points
    66
    Par défaut
    Oups pardon je sais il faut obligatoirement utiliser l'alias
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s = " select site from InfHostingSite site left join fetch site.InfPlatforms where site in (:sites)";

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Collections] map ordonnée + accès par indice
    Par jedimind dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 11/11/2011, 12h43
  2. Réponses: 0
    Dernier message: 06/11/2008, 14h28
  3. Problème de chargement de collection
    Par nephen dans le forum Hibernate
    Réponses: 6
    Dernier message: 04/07/2008, 11h54
  4. Chargement tardif collections ?
    Par maxf1 dans le forum Hibernate
    Réponses: 5
    Dernier message: 31/08/2007, 08h52
  5. [SQL] y a-t-il trop de requêtes ?
    Par bisol dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 27/04/2007, 10h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo