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 :

Hibernate Query HQL - Alternative à MEMBER ?


Sujet :

Hibernate Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Par défaut Hibernate Query HQL - Alternative à MEMBER ?
    Bonjour,

    Je travail sur le debogage d'une application Java servant à extraire des données d'une BDD PostgreSQL.J'ai réussi à cerner le problème et je vais essayer de vous l'exposer facilement. La base de données étant lourde je ne vous présente que les 3 tables importantes.

    Table reponsecomplexe
    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
     
    CREATE TABLE reponsecomplexe
    (
      id bigint NOT NULL,
      codereponse character varying(255),
      valeur character varying(255),
      alias_id character varying(255),
      enquete_code character varying(255),
      numordre integer NOT NULL,
      CONSTRAINT reponsecomplexe_pkey PRIMARY KEY (id ),
      CONSTRAINT fka476da6e93992e18aa842243 FOREIGN KEY (enquete_code)
          REFERENCES enquete (code) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    WITH (
      OIDS=FALSE
    );
    Table ocr
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE ocr
    (
      code character varying(255) NOT NULL,
      nom character varying(255),
      CONSTRAINT ocr_pkey PRIMARY KEY (code )
    )
    WITH (
      OIDS=FALSE
    );
    Table reponsecomplexe_ocr
    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
     
    CREATE TABLE reponsecomplexe_ocr
    (
      reponsecomplexe_id bigint NOT NULL,
      ocr_code character varying(255) NOT NULL,
      CONSTRAINT reponsecomplexe_ocr_pkey PRIMARY KEY (reponsecomplexe_id , ocr_code ),
      CONSTRAINT fkab7fa902e11f1938 FOREIGN KEY (ocr_code)
          REFERENCES ocr (code) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION,
      CONSTRAINT fkab7fa902ef289ca6 FOREIGN KEY (reponsecomplexe_id)
          REFERENCES reponsecomplexe (id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION
    )
    WITH (
      OIDS=FALSE
    );
    Ci-dessous, le mappage des objets dans le code Java :

    ReponseComplexe
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    package inra.fr.enquete.domain;
     
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.Entity;
    import javax.persistence.ManyToMany;
     
    /**
     * classe de modélisation d'une réponse complexe
     * qui est une réponse ordonnée 
     * et qui fait référence une variable précise
     * @author H.BOUSSARD
     */
    @Entity
    public class ReponseComplexe extends Reponse {
     
    	/**
             * Numéro d'ordre, les réponses pouvant être multiples.
             */
    	private int numOrdre; 
     
    	/**
             * Liste d'OCR associées Ã* la réponse.
             */
    	@ManyToMany
    	private Set<OCR> OCR;
     
    	/**
             * Constructeur.
             */
    	protected ReponseComplexe(){}
     
    	/**
             * Constructeur.
             * @param enquete son enquête. 
             * @param alias son alias.
             * @param codeReponse son code réponse.
             * @param numOrdre son numéro d'odre.
             */
    	public ReponseComplexe(Enquete enquete, Alias alias, String codeReponse, int numOrdre){
    		super(enquete,alias,codeReponse);
    		this.numOrdre = numOrdre;
    		this.OCR = new HashSet<OCR>();
    	}
     
    	/**
             * Getter du numéro d'odre.
             * @return le numéro d'odre.
             */
    	public int getNumOrdre(){
    		return numOrdre;
    	}
     
    	/**
             * Setter d'un OCR.
             * @param oCR l'OCR.
             */
    	public void addOCR(OCR oCR){
    		this.OCR.add(oCR);
    	}
     
    	/**
             * Getter des OCR.
             * @return les OCR.
             */
    	public Set<OCR> getOCR(){
    		return OCR;
    	}
     
     
    }
    OCR
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    package inra.fr.enquete.domain;
     
    import java.io.Serializable;
     
    import javax.persistence.Entity;
    import javax.persistence.Id;
     
    /**
     * Classe modelisant tous les OCR, occurence culturales répétées.
     * @author jamanley
     *
     */
    @Entity
    public class OCR implements Serializable  {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 8305794855031527687L;
     
    	/**
             * identifiant.
             */
    	@Id
    	private String code;
     
    	/**
             * Son nom.
             */
    	private String nom;
     
    	/**
             * constructeur.
             */
    	public OCR(){}
     
    	/**
             * Constructeur.
             * @param code son identifiant.
             * @param nom son nom.
             */
    	public OCR(String code, String nom){
    		this.code = code;
    		this.nom = nom;
    	}
     
    	/**
             * Retourne une chaîne de caractères.
             * @return  une chaîne de caractères.
             */
    	public String toString(){
    		return code+" : "+nom;
    	}
     
    	/**
             * getter de son identifiant.
             * @return son identifiant.
             */
    	public String getCode() {
    		return code;
    	}
     
    	/**
             * Getter de son nom.
             * @return son nom.
             */
    	public String getNom() {
    		return nom;
    	}
     
    }
    Une fois cette requête terminé je ne veux garder que les lignes faisant partie d'un OCR particulier choisis au préalable.
    Pour ce faire, la personne m'ayant précédé à fait cela de cette manière :

    Requête HQL hibernate :
    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
     
    from ReponseComplexe r 
    where 
    /** Toute cette partie ne nous interesse pas, elle fonctionne comme il faut.
    r.alias.variable.type = 'multiple' 
    and ( r.alias.variable.code = :variable0 
    or r.alias.variable.code = :variable2 
    or r.alias.variable.code = :variable4 
    or r.alias.variable.code = :variable6 ) 
    and ( r.enquete.departement.code = :departement0 
    or r.enquete.departement.code = :departement1 ) 
    and ( r.enquete.departement.region.code = :region0) 
    and ( r.enquete.culture.code = :culture0) 
    and ( r.enquete.culture.groupe.code = :groupe0) 
    and ( r.enquete.campagne.annee = :campagne0) 
    **/
    and (  :ocr0 MEMBER r.OCR  ) // C'est cette ligne qui m'interesse
    order by r.numOrdre, r.enquete
    Traduction pour le SGBD PostgreSQL :
    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
     
    select reponsecom0_.id as id13_, reponsecom0_.alias_id as alias5_13_, reponsecom0_.codeReponse as codeRepo2_13_, reponsecom0_.enquete_code as enquete4_13_, reponsecom0_.valeur as valeur13_, reponsecom0_.numOrdre as numOrdre14_ 
    from ReponseComplexe reponsecom0_, 
    	( select id, null::varchar as liste_code, alias, variable_code, campagne_annee, 0 as clazz_ from Alias union all select id, liste_code, alias, variable_code, campagne_annee, 1 as clazz_ from AliasAPropositions union all select id, null::varchar as liste_code, alias, variable_code, campagne_annee, 2 as clazz_ from AliasCulture ) alias1_, 
    	Variable variable2_, 
    	Enquete enquete22_, 
    	Departement departemen27_, 
    	Culture culture30_ 
    where reponsecom0_.alias_id=alias1_.id 
    and alias1_.variable_code=variable2_.code 
    and reponsecom0_.enquete_code=enquete22_.code 
    and enquete22_.departement_code=departemen27_.code 
    and enquete22_.culture_code=culture30_.code 
    and variable2_.type='multiple' 
    and (alias1_.variable_code='REG' 
    	or alias1_.variable_code='DEP' 
    	or alias1_.variable_code='CCOMM' 
    	or alias1_.variable_code='COMEXP') 
    and (enquete22_.departement_code='54' 
    	or enquete22_.departement_code='55') 
    and departemen27_.region_code='41' 
    and enquete22_.culture_code='1' 
    and culture30_.groupe_code='1' 
    and (enquete22_.campagne_annee='2001' 
    	or enquete22_.campagne_annee='1994' 
    	or enquete22_.campagne_annee='2006')
    //La traduction de :ocr# MEMBER r.OCR
    and ('HERBICIDE' in (select ocr35_.code 
    		from ReponseComplexe_OCR ocr34_, OCR ocr35_ 
    		where reponsecom0_.id=ocr34_.ReponseComplexe_id 
    		and ocr34_.OCR_code=ocr35_.code)) 
    order by reponsecom0_.numOrdre, reponsecom0_.enquete_code
    Pour résumer, la requête retourne une table de requetecomplexe d'après quelques critère. Jusque la cela fonctionne bien. Une fois arriver au MEMBER (ou IN dans la requete SQL) le SGBD recherche le ou les OCR de chaque requete complexe à l'aide de la table requetecomplexe_ocr et ne concerve que les lignes qui pointent sur un OCR correspondant à l'OCR choisis (ici HERBICIDE).

    Le problème est que, certaine requête ne dure que quelques seconde et d'autre plus d'une heure ce qui n'est absolument pas envisageable.

    Une alternative qui marche très bien en SQL et d'ajouter dans le from la table requetecomplexe_ocr, d'ajouter les conditions requetecomplexe_ocr.code = 'HERBICIDE' et requetecomplexe.id = requetecomplexe_ocr.requetecomplexe_id

    Exemple :

    Traduction pour le SGBD PostgreSQL :
    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
     
    select reponsecom0_.id as id13_, reponsecom0_.alias_id as alias5_13_, reponsecom0_.codeReponse as codeRepo2_13_, reponsecom0_.enquete_code as enquete4_13_, reponsecom0_.valeur as valeur13_, reponsecom0_.numOrdre as numOrdre14_ 
    from ReponseComplexe reponsecom0_, 
    	( select id, null::varchar as liste_code, alias, variable_code, campagne_annee, 0 as clazz_ from Alias union all select id, liste_code, alias, variable_code, campagne_annee, 1 as clazz_ from AliasAPropositions union all select id, null::varchar as liste_code, alias, variable_code, campagne_annee, 2 as clazz_ from AliasCulture ) alias1_, 
    	Variable variable2_, 
    	Enquete enquete22_, 
    	Departement departemen27_, 
    	Culture culture30_, 
            //On ajoute la table reponsecomplexe_ocr aux sources
            ReponseComplexe_OCR ocr31_
    where reponsecom0_.alias_id=alias1_.id 
    and alias1_.variable_code=variable2_.code 
    and reponsecom0_.enquete_code=enquete22_.code 
    and enquete22_.departement_code=departemen27_.code 
    and enquete22_.culture_code=culture30_.code 
    and variable2_.type='multiple' 
    and (alias1_.variable_code='REG' 
    	or alias1_.variable_code='DEP' 
    	or alias1_.variable_code='CCOMM' 
    	or alias1_.variable_code='COMEXP') 
    and (enquete22_.departement_code='54' 
    	or enquete22_.departement_code='55') 
    and departemen27_.region_code='41' 
    and enquete22_.culture_code='1' 
    and culture30_.groupe_code='1' 
    and (enquete22_.campagne_annee='2001' 
    	or enquete22_.campagne_annee='1994' 
    	or enquete22_.campagne_annee='2006')
    //La modification :
    and ocr31_.code = 'HERBICIDE'
    and reponsecom0_.id = ocr31_.reponsecomplexe_id
    order by reponsecom0_.numOrdre, reponsecom0_.enquete_code
    Le modèle objet du code java ne possède pas d'objet pour la table reponsecomplexe_ocr, la table ne servant qu'au mapping entre, les tables et objets, reponsecomplexe et ocr.

    Je cherche un moyen d'effectuer ma requête simplement sans revoir la conception du modèle coté java (J'ai à peine une semaine d'expérience dans tout ces framework qui sont tout nouveau pour moi).

    Ce que j'aimerais au final, c'est modifier cette partie de la création de la requête HQL en touchant le moins possible au mapping :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if(ocr.size() > 0){
    			b.append(" and ( ");
    			b.append(" :ocr0 MEMBER r.OCR ");
    			for(int i=1; i<ocr.size(); i++){
    				b.append(" or :ocr"+i+" MEMBER r.OCR");
    			}
    			b.append(" ) ");
    		}
    Si vous avez des informations sur le pourquoi le "IN" peut être si gourmand en temps (certaines requète durait plus d'une heure alors que la table de départ avant le IN est vide la ou le WHERE ne dure que quelques seconde.), je suis preneur aussi.

    Merci de m'avoir lu jusqu'ici.

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2010
    Messages : 95
    Par défaut
    Beaucoup de blabla pour finalement pas grand chose.

    J'ai juste modifié la manière de lier ma table OCR à la table ReponseComplexe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    select r //Necessaire à cause de la jointure sinon l'objet récupéré n'est plus de la classe ReponseComplexe
    from ReponseComplexe r 
    //Je fais une jointure sur OCR pour récupérer les OCR de la réponse complexe
    join r.OCR ocr
    where 
    /** 
    ...
    **/
     
    //and (  :ocr0 MEMBER r.OCR  )  Je vire cette condition et la remplace par 
    and ocr.code = :ocr0
    //Qui filtre donc les reponse en fonction de l'OCR choisis
    order by r.numOrdre, r.enquete

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

Discussions similaires

  1. hibernate query language
    Par marwen2300 dans le forum Hibernate
    Réponses: 1
    Dernier message: 24/04/2007, 09h03
  2. [Hibernate 3][HQL] erreur de Delete
    Par CharlSka dans le forum Hibernate
    Réponses: 5
    Dernier message: 20/04/2007, 16h02
  3. [Hibernate 3] [HQL] Faire un Insert via HQL
    Par bouchette63 dans le forum Hibernate
    Réponses: 3
    Dernier message: 09/11/2006, 17h05
  4. [Hibernate] Queries et relation NN
    Par azpublic dans le forum Hibernate
    Réponses: 10
    Dernier message: 23/01/2006, 10h52

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