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 :

Jointure requete HQL


Sujet :

Hibernate Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut Jointure requete HQL
    Bonjour à tous,

    Ca fait plus d'une journée que je perd mon temps à essayer de formuler correctement une requete hql en vain, j'ai réellement besoin de votre aide car je ne peux pas perdre plus de temps la dessus.

    Le problème se passe sur des jointures que je ne dois pas effectuer correctement car sois la requete est fausse et tomcat me sors une erreur, sois la requete passe mais le résultat escompté n'est pas bon.

    Tout d'abord voici le schéma physique de la base de données :



    Je veux faire une jointure entre :

    users(id_user) - usersaddress(id_user)
    users(id_user) - userslinkgroups(id_user)
    userslinkgroups(id_user_group) - accessrights(id_user_group)

    Et voici la requete SQL qui me donne ce bon résultat :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT u.*, ar.* FROM 
     
    Users u LEFT JOIN usersaddress ua ON u.id_user = ua.id_user 
     
    LEFT JOIN userslinkgroups ulg ON ulg.id_user = u.id_user 
     
    LEFT JOIN access_rights ar ON ar.id_user_group = ulg.id_user_group 
     
    WHERE u.id_user = 0;
    Le problème c'est que je n'arrive pas a transposer cette requete en HQL, et ca fait un ptit moment que je commence a me prendre la tete la dessus...

    Au niveau de mes classes et de leur variable d'instance (j'ai juste mis celle utile pour résoudre mon problème), voici ce que cela donne ci dessous.

    - Users
    -> Set<Usersaddress>
    -> Set<Usersgroups>

    - Usersaddress
    -> Users

    - Userslinkgroups
    -> Users
    -> Usersgroups

    - Usersgroups
    -> Users

    - AccessRights
    -> Usersgroups

    Merci pour vos réponses !!

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Je UP car j'ai totalement changer le post d'origine.

  3. #3
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    hum je pense que tu as essayé une requête du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select u, ar from Users u 
    left join u.Usersaddress ua 
    left join u.Usersgroups ug
    left join ug.AccessRights ar # il ne manque pas une relation entre groups et accessrights ?
    where u.id = 0
    tu n'utilises pas cette usersaddress dans ton select, est-ce utile de la mettre ?

    quel est le problème avec cette requête ?
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  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
    Essaie peut-être ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select u, ar
    from Users u, AccessRights ar
    left join u.Usersaddress
    left join u.Usersgroups
    left join ar.Usersgroups
    where u.id = 0
    Voire peut-être un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select u, ar
    from Users u, AccessRights ar
    left join u.Usersaddress
    left join u.Usersgroups ug1
    left join ar.Usersgroups ug2
    where u.id = 0 and ug1 = ug2

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Merci pour vos réponses !

    Gardyen :

    ta requete ne fonctionne pas car lorsque tu fais

    left join u.Usersgroups ug
    left join ug.AccessRights ar
    Usersgroups ne contient pas d'élément AccessRights donc forcémment il rale...

    fr1man :

    Ta 2ème requete fonctionne a merveille

    select u, ar
    from Users u, AccessRights ar
    left join u.Usersaddress
    left join u.Usersgroups ug1
    left join ar.Usersgroups ug2
    where u.id = 0 and ug1 = ug2
    En effet je peux meme la simplifier sans l'addresse

    SELECT u, ar FROM Users u, AccessRights ar
    LEFT JOIN u.Usersgroups ug1
    LEFT JOIN ar.IdUserGroup ug2
    WHERE u.id = :id AND ug1 = ug2
    En revanche je ne comprend pas pourquoi la requete ne peux pas etre encore simplifier de la sorte, dans ce cas ci dessous il me sort tout les AccessRights de la base et pas ceux seulement de l'User

    SELECT u, ar FROM Users u, AccessRights ar
    LEFT JOIN u.Usersgroups
    WHERE u.id = :id
    Normalement la jointure devrait etre efficace comme ceci ??
    ce n'est pas le cas...
    Pourquoi faut il absolument rajouter la condition "AND ug1 = ug2" dans la clause WHERE et cette jointure en plus ("LEFT JOIN ar.IdUserGroup ug2") ???

    D'avance merci.

  6. #6
    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 assez normal, car dans ta clause from, tu spécifies une table AccessRights mais tu ne fais pas de jointure dessus, tu vas donc avoir un produit cartésien entre Users et AccessRights.

    Tu as besoin de la jointure en plus et de l'égalité pour filtrer sur les mêmes lignes de Usersgroups.

    C'est surement pas très clair ce que je raconte...

  7. #7
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    ta dernière requête ne peut pas marcher, tu ne définis pas de condition de jointure vers accessrights, donc toutes les lignes de ar sont gardées...

    c'est pourquoi tu as besoin de rajouter:
    -> la jointure entre accessrights et usersgroups: LEFT JOIN ar.IdUserGroup ug2
    -> la condition d'égalité pour n'avoir que les groupes lies a ton user: ug1 = ug2

    si tu veux la simplifier, il te faut ajouter la réciproque de ta relation accessrights.usersgroups dans ton mapping (je sais j'insiste sur cette relation )

    La requete sera alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT u, ar FROM Users u
    LEFT JOIN u.Usersgroups ug
    LEFT JOIN ug.AccessRights ar
    WHERE u.id = :id
    edit: grilled
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Si j'ai bien compris...

    Avec ca :

    SELECT u, ar FROM Users u, AccessRights ar
    LEFT JOIN u.Usersgroups
    WHERE u.id = 1
    Je pensais que la ligne :

    AccessRights ar LEFT JOIN u.Usersgroups

    Suffisait a faire la jointure entre les 2 tables mais apparement ca ne suffit pas, a ce stade les 2 tables ne sont pas liés... C'est dans le where qu'elle se lie physiquement a priori...

    En tout cas merci à vous 2 pour vos réponses !

  9. #9
    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
    Ben le lien left join porte sur Users et Usersgroups.
    Ce sont ces deus tables qui sont liées.
    AccessRights est juste nommée dans le from, pas "jointurée"

    Ceci dit, si tu peux, fais comme Gardyen te le conseille, modifie ton mapping.
    Il est d'ailleurs recommandé dans la doc, les associations bidirectionnelles, pour une meilleur navigation, notamment dans les requêtes.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Bon alors en fait j'ai criée victoire trop tot, le probleme n'est pas résolue et pour cause...

    Et oui du coup si je met la jointure dans le AND "and ug1 = ug2", le résultat en sortie ne comprend que les utilisateurs qui sont dans un groupe !!!

    Et mon LEFT OUTER JOIN ne sers donc plus a rien, lui qui est censé faire la JOINTURE...

    Je ne pense pas qu'il faille mettre la jointure dans le AND mais bien comme dans la requete SQL, seulement dans les LEFT JOIN... bref je suis complètement perdu et je commence a en avoir un peu marre de cette hibernate...

    MERCI POUR VOTRE AIDE !!! snif !

  11. #11
    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
    Et la première requête que je t'ai donné te renvoyait quoi ?

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    Elle me renvoit la table AccessRights complète...

  13. #13
    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
    Et si tu parcours dans l'autre sens, un peu de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select u, ar
    from AccessRights ar left join ar.Usersgroups ug
    right join ug.Users u
    where u.id_user = 0
    EDIT: ce serait plutôt un left join sur la première jointure

  14. #14
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    si tu veux n'utiliser que les left join tu peux faire aussi ceci:

    select u, ar
    from Users u, AccessRights ar
    left join u.Usersgroups ug1
    left join ar.Usersgroups ug2
    where u.id = 0 and ((ug1 = ug2) or ug1 is null)
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    135
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 135
    Points : 81
    Points
    81
    Par défaut
    f1man :

    La première requete me renvoie un :

    org.hibernate.HibernateException: Found shared references to a collection: org.nasr.database.Users.Usersgroups

    Gardyen :

    Il me sort l'utilisateur unique mais toutes les lignes de la table accessrights.

    Je commence a me poser de sérieuse question sur hibernate, la requete HQL que je veux faire est on ne peut plus simple et pour l'instant je n'ai aucune solution... J'ai pourtant lu dans la doc qu'il s'agissait d'un moyen plus rapide et plus compréhensible puisque objet d'effectuer des requetes HQL que SQL, mais la je ne doute plus je suis sur du contraire ! Franchement j'ai mis 5 minutes a faire la requete SQL et ca fait 4 jours que j'essaye de faire la requete HQL correspondante !!!

  16. #16
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    hibernate est très utile, en particulier au niveau des associations, si le mapping a été fait correctement.

    dans ton cas le mapping est incomplet, rendant effectivement hql moins efficace.

    a ta place, j'utiliserai les outils existants pour refaire un mapping clean.
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

Discussions similaires

  1. requete HQL + multiple cle + jointures
    Par Vire7777 dans le forum Hibernate
    Réponses: 2
    Dernier message: 09/11/2010, 10h58
  2. Unexpected Token dans requete HQL avec jointures
    Par philoo_le_foo dans le forum Hibernate
    Réponses: 18
    Dernier message: 22/04/2010, 19h48
  3. Requete avec jointure en HQL
    Par Alyx² dans le forum Hibernate
    Réponses: 2
    Dernier message: 14/05/2008, 09h13
  4. Requete HQL avec jointure
    Par chriscoolletoubibe dans le forum Hibernate
    Réponses: 50
    Dernier message: 24/04/2007, 15h54
  5. [jointure]requete possible de double jointure entre 2 tables
    Par akira_le_gaucher dans le forum Langage SQL
    Réponses: 4
    Dernier message: 11/05/2004, 15h03

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