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 :

HQL avec critère


Sujet :

Hibernate Java

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut HQL avec critère
    Bonjour,

    Je désire effectué une requête sur deux tables qui ont une relation many-to-many avec un critère de selection sur chaque table. le mapping des tables est le suivant:

    Team.hbm.xml:
    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
     
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="com.yannick.lombard.gwt.client.model.Team" table="TEAMS">
            <id name="id" type="int" column="ID">
                <generator class="increment"/>
            </id>
            <property name="teamName" type="string">
                <column name="TEAM_NAME"  not-null="true" />
            </property>
            <property name="teamTown" type="string">
                <column name="TEAM_TOWN"  not-null="true" />
            </property>
            <property name="teamAbbrev" type="string">
                <column name="TEAM_ABBREV"  not-null="true" />
            </property>
            <property name="teamStadiumName" type="string">
                <column name="TEAM_STADIUM_NAME"  not-null="true" />
            </property>
            <property name="teamFoundationYear" type="string">
                <column name="TEAM_FOUNDATION_YEAR"  not-null="false" />
            </property>
     
            <many-to-one name="country" column="country_id" not-null="false" class="com.yannick.lombard.gwt.client.model.Country" />
     
            <set name="seasons" table="teams_seasons" lazy="false">
          		<key column="team_id"/>
          		<many-to-many class="com.yannick.lombard.gwt.client.model.Season" column="season_id"/>
        	</set>
     
      </class>
    </hibernate-mapping>
    Season.hbm.xml:
    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
     
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="com.client.model.Season" table="SEASONS" lazy="false">
      		<id name="id" type="int" column="ID">
          		<generator class="increment"/>
        	</id>
     
        	<property name="seasonYear" type="string">
        		<column name="SEASON_YEAR"  not-null="true" />
            </property>
     
            <set name="teams" table="teams_seasons" lazy="false">
          		<key column="season_id"/>
          		<many-to-many class="com.yannick.lombard.gwt.client.model.Team" column="team_id"/>
        	</set>
      </class>
    </hibernate-mapping>
    Country.hbm.xml:
    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
     
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
      <class name="com.client.model.Country" table="COUNTRIES" lazy="false">
            <id name="id" type="int" column="ID">
                <generator class="increment"/>
            </id>
            <property name="countryName" type="string">
                <column name="COUNTRY_NAME"  not-null="true" />
            </property>
            <property name="countryAbbrev" type="string">
                <column name="COUNTRY_ABBREV"  not-null="true" />
            </property>
      </class>
    </hibernate-mapping>
    Je désire récupérer toute les teams avec un country_id et un season_id.

    J'ai mis une image de la base en pièce jointes.
    Images attachées Images attachées  

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    c'est pas clair au niveau de ta question, tu veux toutes les teams qui ont des infos pour country et season, ou tu veux toutes les teams qui ont un country et une season donnés ?

    dans les 2 cas je te conseille d'utiliser l'api Criteria d'hibernate, ça donnera quelque chose comme ça pour la première option:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Criteria criteria = session.createCriteria(Team.class);
    criteria.add(Restrictions.isNotNull("country"));
    criteria.createCriteria("seasons").add(Restrictions.isNotNull("id"));

  3. #3
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Bonjour,

    Merci pour ta réponse.
    Je vais essayer d'être plus clair.
    Si tu prends l'image de la base que j'ai mis en pièce jointe,
    je voudrais la requête hql ou autre qui répond à cette requête SQL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Select a.* 
    from teams a, teams_seasons  b, seasons c
    where a.country_id = param1
    and a.id = b.team_id
    and b.season_id = c.id
    and c.id = param2
    Merci

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    dans ce cas c'est la 2e option, donc au choix Criteria
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Criteria criteria = session.createCriteria(Team.class);
    criteria.add(Restrictions.eq("library.id", param1));
    criteria.createCriteria("seasons").add(Restrictions.eq("id", param2));
    en HQL, ça devrait donner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    "select xs.id
    from Team a
    join a.seasons as b
    where a.country.id = "+param1+"
    and b.id = "+param2
    mais je suis moins à l'aise, j'utilise les Criteria en général. Il doit par exemple y avoir un moyen d'utiliser des requêtes paramétrées avec hql

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Merci pour tes réponses éclairées qui me font avancer.

    J'ai modifier la requête de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "select distinct team from Team team right outer join team.seasons as season where team.country.id = :countryId";
    Celle ci fonctionne correctement à partir du principe ou il existe au moins une référence pour une équipe dans chaque table.
    Par contre si l'équipe est présente dans la table team et que celle-ci n'a aucune référence dans la table team_season et season celle-ci n'est pas récupérée par la requête.

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    J'ai modifié la requête et la ça marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select distinct team from Team team left outer join team.seasons as season where team.country.id = :countryId;

  7. #7
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Par contre j'aurais aimé améliorer ma requête.

    Je désirerai récupérer toutes les teams pour un country et une season même si cette équipe n'a aucun référencement dans la table de liaison team_seaon.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select team from Team team left outer join team.seasons as season where team.country.id = :countryId and season.id = :seasonId
    J'ai la requête suivante mais elle est trop exclusive car elle ne me ramène pas les équipes qui ne sont pas référencées dans la table de liaison team_seaon.

    Merci

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    euh pas clair ce que tu veux...

    Je désirerai récupérer toutes les teams pour un country et une season même si cette équipe n'a aucun référencement dans la table de liaison team_seaon.
    autrement dit, tu veux toutes les équipes d'un certain country ?

  9. #9
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Je vais essayer de clarifier.

    En suivant le schéma de base de données en pièce jointe.

    On imagine que j'ai deux teams qui sont référencées dans la table teams mais une seule de ces deux team référence une saison, c'est à dire qu'elle possède une entrée dans la table teams_seasons.

    Je veux pouvoir récupécurer toutes les équipes pour le même pays même si elles n'ont pas d'entrée dans la table teams_seasons.

    Je pense que c'est clair avec le schéma.

    Merci

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    euh... ma confusion vient de ce que ta requête
    select distinct team from Team team left outer join team.seasons as season where team.country.id = :countryId;
    te donne ce que tu veux, non ?

    elle te retourne toutes les équipes avec le country = countryId, cela inclut les celles qui ne sont pas mappées à une season.

    si tu veux aussi les infos de season, tu dois les ajouter dans le select genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select distinct team, season.seasonYear

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    ah ok !!!
    je comprends vite mais faut m'expliquer longtemps

    dans ce cas un 'ou' est nécessaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select team from Team team left outer join team.seasons as season where team.country.id = :countryId and (season.id = :seasonId or season.id is null)

  12. #12
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Oui effectivement ta requête fonctionne mais mon but était de diminuer le nombre de requête Hibernate en faisant une requête de ce type là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select team from Team team left outer join team.seasons as season where team.country.id = :countryId and season.id = :seasonId
    Mais si l'équipe ne possède aucune entrée dans la table teams_seasons, elle n'est pas remonté

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    euh tu parles de celle avec le ou ????

  14. #14
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Excuse moie je n'avais pas vu ta dernière réponse.

    J'ai essayé ta requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select team from Team team left outer join team.seasons as season where team.country.id = :countryId and (season.id = :seasonId or season.id is null)
    mais elle ne fonctionne pas...

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    et en quoi elle ne fonctionne pas ? erreur de syntaxe ? pas les résultats escomptés ? elle ne fait pas le café ? la pizza n'est pas cuite ?

    je l'ai testé sur ma base de données, et ça a retourné ce que j'attendais

  16. #16
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Excuse moi j'étais reparti dans mes pensées.

    Lorsque j'effectue cette requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select distinct team from Team team left outer join team.seasons as season where team.country.id = :country_Id and (season.id = :season_Id or season.id is null)
    Je n'obtiens que les équipes qui ont le bon season_id passé en paramètre.
    La requête ne plante pas, elle ne me ramène pas toute les entrées.

    Voici la requête hibernate qui est générée dans le log
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select distinct team0_.ID as ID14_, team0_.TEAM_NAME as TEAM2_14_, team0_.TEAM_TOWN as TEAM3_14_, team0_.TEAM_ABBREV as TEAM4_14_, team0_.TEAM_STADIUM_NAME as TEAM5_14_, team0_.TEAM_FOUNDATION_YEAR as TEAM6_14_, team0_.country_id as country7_14_ from TEAMS team0_ left outer join teams_seasons seasons1_ on team0_.ID=seasons1_.team_id left outer join SEASONS season2_ on seasons1_.season_id=season2_.ID where team0_.country_id=? and (season2_.ID=? or season2_.ID is null)

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    cette requête me donne le résultat attendu dans mon cas... des teams avec un season_id et des teams sans...
    tu es sur que tu as des teams sans season pour ce season id ?

  18. #18
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 196
    Par défaut
    Bonjour,

    Pour répondre à ta question j'ai 2 équipes dans la table Teams j'ai une saison dans la table Seasons je n'ai qu'une seule des deux équipes qui référence une saison dans la table Teams_Seasons et lorsque j'effectue la dite requête seule l'équipe qui référence la saison est récupérée. Mystère!!! Surtout si chez toi cela fonctionne. Je me dis que chez moi j'ai quelque chose qui manque ou est en trop.

    Merci

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    la seule différence entre nous deux, ce sont tes données à priori...
    peux-tu regarder de ce côté ou les donner ici ?

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

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    voilà mes tables de test, j'ai juste enlevé quelques colonnes

    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
    countries:
    "id"	"name"
    "1"	"France"
    "2"	"Allemagne"
     
    teams:
    "id"	"team_name"	"country_id"
    "1"	"team_1"	"1"
    "2"	"team_2"	"1"
     
    seasons:
    "id"	"season_year"
    "1"	"2012"
     
    teams_seasons:
    "team_id"	"season_id"
    "1"	"1"
    et la requête
    select distinct team0_.id as ID14_, team0_.team_name as TEAM2_14_, team0_.country_id as country7_14_, season2_.season_year
    from teams team0_
    left outer join teams_seasons seasons1_ on team0_.ID=seasons1_.team_id
    left outer join seasons season2_ on seasons1_.season_id=season2_.id
    where team0_.country_id=1 and (season2_.ID=1 or season2_.ID is null)
    me renvoie comme résultats:
    "ID14_" "TEAM2_14_" "country7_14_" "season_year"
    "1" "team_1" "1" "2012"
    "2" "team_2" "1" NULL

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/01/2012, 17h59
  2. Requêtes sur enregistrements avec critères dates
    Par Aliveli dans le forum Access
    Réponses: 10
    Dernier message: 05/06/2006, 13h41
  3. Pb requête avec critères dans projet Access
    Par laville dans le forum Access
    Réponses: 4
    Dernier message: 19/04/2006, 20h09
  4. [DOM] Récupération d'un noeud avec critères ?
    Par elitost dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 20/10/2005, 15h27
  5. [Excel] Selection multiple avec critères
    Par tibotibotibo dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 26/04/2005, 10h48

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