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 :

Jointures implicites générées trop nombreuses


Sujet :

Hibernate Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 5
    Points : 6
    Points
    6
    Par défaut Jointures implicites générées trop nombreuses
    Bonjour,

    Je suis plutot débutant en hibernate et mon problème est que lorsque j'utilise une requête avec des critères un peu avancés en hql, en utilisant des jointures implicites, hibernate me génère une requête avec beaucoup trop de jointures, qui sont inutiles car redondantes.


    J'ai 3 tables dont les mappings, générés par hibernate tools, sont les suivants :
    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
    <class name="vtpro.model.OrgPersonnel" table="ORG_PERSONNEL">
            <id name="idPersonnel" type="integer">
                <column name="ID_PERSONNEL" precision="22" scale="0" />
                <generator class="assigned" />
            </id>
            <property name="compteSesame" type="string">
                <column name="COMPTE_SESAME" length="100" />
            </property>
            <set name="orgAffectPersonnels" inverse="true">
                <key>
                    <column name="ID_PERSONNEL" precision="22" scale="0" not-null="true" />
                </key>
                <one-to-many class="vtpro.model.OrgAffectPersonnel" />
            </set>
        </class>


    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
        <class name="vtpro.model.OrgPoste" table="ORG_POSTE">
            <id name="idPoste" type="integer">
                <column name="ID_POSTE" precision="22" scale="0" />
                <generator class="assigned" />
            </id>
            <property name="descPoste" type="string">
                <column name="DESC_POSTE" length="50" />
            </property>
            <property name="posteActif" type="string">
                <column name="POSTE_ACTIF" length="1" />
            </property>
            <property name="dateDebutValidite" type="date">
                <column name="DATE_DEBUT_VALIDITE" length="7" />
            </property>
            <property name="dateFinValidite" type="date">
                <column name="DATE_FIN_VALIDITE" length="7" />
            </property>
            <set name="orgAffectPersonnels" inverse="true">
                <key>
                    <column name="ID_POSTE" precision="22" scale="0" not-null="true" />
                </key>
                <one-to-many class="vtpro.model.OrgAffectPersonnel" />
            </set>
        </class>


    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
        <class name="vtpro.model.OrgAffectPersonnel" table="ORG_AFFECT_PERSONNEL">
            <id name="idAffectPersonnel" type="integer">
                <column name="ID_AFFECT_PERSONNEL" precision="22" scale="0" />
                <generator class="assigned" />
            </id>
            <many-to-one name="orgPoste" class="vtpro.model.OrgPoste" fetch="select">
                <column name="ID_POSTE" precision="22" scale="0" not-null="true" />
            </many-to-one>
            <many-to-one name="orgPersonnel" class="vtpro.model.OrgPersonnel" fetch="select">
                <column name="ID_PERSONNEL" precision="22" scale="0" not-null="true" />
            </many-to-one>
            <property name="dateDebutOccupation" type="date">
                <column name="DATE_DEBUT_OCCUPATION" length="7" not-null="true" />
            </property>
            <property name="dateFinOccupation" type="date">
                <column name="DATE_FIN_OCCUPATION" length="7" />
            </property>
        </class>


    Ma requête est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    from OrgPersonnel as p
    where p.compteSesame = 'toto@toto.fr'
    and p.orgAffectPersonnels.dateDebutOccupation <= current_date()
    and (p.orgAffectPersonnels.dateFinOccupation IS NULL
    or p.orgAffectPersonnels.dateFinOccupation >= current_date())
    et il me génère :
    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
    select
      orgpersonn0_.ID_PERSONNEL as ID1_4_,
      orgpersonn0_.COMPTE_SESAME as COMPTE2_4_,
     from
      VTPRO.ORG_PERSONNEL orgpersonn0_,
      VTPRO.ORG_AFFECT_PERSONNEL orgaffectp1_,
      VTPRO.ORG_AFFECT_PERSONNEL orgaffectp2_,
      VTPRO.ORG_AFFECT_PERSONNEL orgaffectp3_
     where
      orgpersonn0_.ID_PERSONNEL=orgaffectp3_.ID_PERSONNEL
      and orgpersonn0_.ID_PERSONNEL=orgaffectp2_.ID_PERSONNEL
      and orgpersonn0_.ID_PERSONNEL=orgaffectp1_.ID_PERSONNEL
      and orgpersonn0_.COMPTE_SESAME='toto@toto.fr'
      and orgaffectp1_.DATE_DEBUT_OCCUPATION<=current_date
      and (
       orgaffectp2_.DATE_FIN_OCCUPATION is null
       or orgaffectp3_.DATE_FIN_OCCUPATION>=current_date
      )

    Comme vous pouvez le constater, il génère 3 jointures sur ORG_AFFECT_PERSONNEL, tandis qu'une seule serait suffisante.

    Donc je dois avoir un problème quelque part, dans ma requête ou bien dans mon mapping. Mais je ne vois pas très bien




    --------------------------------------------------------------------

    De plus j'ai d'autres critères à ajouter sur les postes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    and p.orgAffectPersonnels.orgPoste.posteActif='1'
    AND p.orgAffectPersonnels.orgPoste.dateDebutValidite >= current_date()
    AND (p.orgAffectPersonnels.orgPoste.dateFinValidite IS NULL
    OR p.orgAffectPersonnels.orgPoste.dateFinValidite <= current_date()))
    Mais lorsque je teste la requete complete dans hql editor, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "org.hibernate.QueryException: could not resolve property: posteActif of: vtpro.model.OrgAffectPersonnel"
    Pourtant je lui dis bien p.orgAffectPersonnels.orgPoste.posteActif

    J'en déduis que j'ai un problème dans ma syntaxe mais je n'arrive pas trop à comprendre comment le contourner. La doc ne m'a pas beaucoup aidé.
    Je suppose qu'il faut que je fasse quelque chose pour pouvoir accéder à un élément qui se trouve dans un set (p.orgAffectPersonnels). Mais j'ai pas trouvé quoi.



    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
    Tu dois spécifier dans ta requête la jointure vers une collection.
    Essaie un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    from OrgPersonnel as p inner join p.orgAffectPersonnels as ap
    where p.compteSesame = 'toto@toto.fr'
    and ap.dateDebutOccupation <= current_date()
    and (ap.dateFinOccupation IS NULL
    or ap.dateFinOccupation >= current_date())

  3. #3
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 5
    Points : 6
    Points
    6
    Par défaut
    Merci !! Mon premier problème est résolu.
    Il semblerait que les jointures implicites soient à éviter dans ce genre de cas.

    La requête indiquée me renvoie toujours trop de résultats, mais ce coup-ci c'est juste que j'ai une ligne par poste associé au personnel, donc des doublons.

    Mais avec cette requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    select p from OrgPersonnel as p inner join p.orgAffectPersonnels as ap
    where p.compteSesame = 'toto@toto.fr'
    and ap.dateDebutOccupation <= current_date()
    and (ap.dateFinOccupation IS NULL
    or ap.dateFinOccupation >= current_date())
    associé à un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     session.createQuery(...).uniqueResult();
    Je peux n'obtenir qu'un seul objet.

    Bref, les jointures implicites c'était une mauvaise idée .

    Mon 2e problème est aussi résolu en ajoutant une jointure supplémentaire.

    Merci.

  4. #4
    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
    C'est juste que :
    - pour une jointure vers un objet, la jointure implicite suffit
    - pour une jointure vers une collection il faut la déclarer

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/11/2009, 03h51
  2. [HQL] jointure implicite dans un sous-select
    Par Manopower dans le forum Hibernate
    Réponses: 1
    Dernier message: 09/09/2009, 11h45
  3. Imbrications trop nombreuses - Mon code part trop sur la droite
    Par Sve@r dans le forum Général Python
    Réponses: 11
    Dernier message: 24/02/2008, 11h03
  4. [VB 6.0 + sql server] pb insertion de lignes trop nombreuses
    Par flores dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 30/10/2006, 16h29
  5. Probleme jointure trop de résultats
    Par krovomi dans le forum Requêtes
    Réponses: 3
    Dernier message: 28/06/2006, 09h24

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