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

Frameworks Web Java Discussion :

HQL : récupérer une liste d'objets et les compter


Sujet :

Frameworks Web Java

  1. #1
    Membre du Club Avatar de Lovegiver
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2015
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2015
    Messages : 81
    Points : 57
    Points
    57
    Par défaut HQL : récupérer une liste d'objets et les compter
    Bonjour,

    dans le cadre d'une appli Web, j'utilise Hibernate et HQL, son langage de requêtage.

    J'ai un problème que je ne parviens pas à résoudre alors qu'il semble simple a priori :

    Je souhaite extraire les données d'une table (qui correspond à un objet A) avec une jointure sur une autre table (objet B) et, surtout, compter le nombre de fois que chaque B apparait.
    -> ceci implique que mes objets sont liés entre eux dans mes classes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MaClasseA {
      private String attribut1;
      private MaClasseB attribut2;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MaClasseB {
      private int attribut1;
      ...
    }

    En HQL la requête serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select a from ObjetA as a left join fetch a.attribut2 as b
    Et normalement, pour compter, elle devrait devenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select a, count(b) from ObjetA as a left join fetch a.attribut2 as b
    Primo : Actuellement, je ne parviens pas à faire tourner cette requête alors que je suis assez scrupuleusement les différentes sources que j'ai trouvé sur le web. Est-ce que quelqu'un voit une erreur ?
    Deuxio : la requête va me renvoyer une liste. Normalement, pour afficher le contenu de cette liste dans ma page Web avec JSTL, je vais nommer cette liste avec un setAttribute("MaListe", maListe) puis interroger chaque attribut de la façon suivante : ${MaListe.attribut1}, etc.
    --> comment récupérer les valeurs issues du comptage de la requête ? comment se nomme cet attribut ? J'ai essayé "count" mais ça ne fonctionne pas.

    Merci d'avance à ceux qui connaissent HQL pour leur aide bienveillante.

  2. #2
    Membre confirmé Avatar de freddou17
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 341
    Points : 566
    Points
    566
    Par défaut
    salut,

    tu fais une jointure par la gauche (left join) donc tu auras tu 1 pour 1 alors que le count est une fonction d’agrégation.

    objet 1 MaClasseA objet 1 MaClasseB
    objet 1 MaClasseA objet 2 MaClasseB
    objet 1 MaClasseA objet 3 MaClasseB
    objet 2 MaClasseB objet 4 MaClasseB

    tu n'auras toujours qu'un seul objet de ta classe B.
    Donc soit tu fais un count seul avec une clause where ou tu récupères une liste d'objet de la classe B grâce à ton mapping (one to many) à laquelle tu appliqueras la méthode size() dans ton code java.

    https://docs.jboss.org/hibernate/core/3.3/reference/fr-FR/html/queryhql.html
    http://docs.jboss.org/hibernate/orm/...llections.html

    attention aux version d'hibernate référencés dans les liens.

    Bon courage
    ++
    "Aucun de nous ne sait ce que nous savons tous, ensemble."
    Lien vers mon appli Funcash n'hésitez pas à donner votre avis

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Salut.
    Tu peux parcourir ta liste et utiliser une variable qui te donnerait le nombre de tours qu'a fait la boucle ce qui correspond au nombre d'éléments.

  4. #4
    Membre du Club Avatar de Lovegiver
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2015
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2015
    Messages : 81
    Points : 57
    Points
    57
    Par défaut
    Bonjour @freddou17 et @Kasko

    merci pour vos réponses et surtout mes excuses pour cette absence de réponse de ma part à vos suggestions.

    J'ai dû avancer sur le code d'autres parties de l'application, essayant de trouver une solution à ce problème à mes heures perdues (celles du sommeil en général, vous connaissez ça sans doute).

    A l'heure qu'il est, je n'ai toujours pas réussi à faire tourner cette maudite requête et je suis fort embêté.

    Le site sur lequel je travaille est un site qui vend des offres de voyage / loisir : hébergement, restau, activités diverses comme des spectacles, etc.

    Chaque offre dispose déjà de nombreuses infos expliquant de quoi il s'agit, mais le vendeur a le moyen d'ajouter des étiquettes sur son offre, 5 au maximum, permettant d'apporter un visuel supplémentaire sur la page.

    Par exemple : un vendeur propose un semaine de séjour à Barcelone. Il peut "tagger" son offre avec des mots comme : "Espagne", "Barcelone" et "Sagrada Familia".

    Si j'ai d'autres offres avec le tag "Espagne", un clic du client sur le tag lui permet de visualiser toutes les offres en rapport avec "Espagne".

    Ca ça fonctionne, c'était pas bien compliqué.

    La fonctionnalité sur laquelle je butte est toute simple. Imaginons 3 offres et leur tags respectifs :
    - offre 1 : "Espagne", "Corrida", "Costa del Sol"
    - offre 2 : "Espagne", Tapas", "Grenade"
    - offre 3 : "France", "Pays Basque", "Tapas", "Surf"

    Ce que je dois sortir, c'est la liste suivante :
    - Espagne : 2
    - Tapas : 2
    - Corrida : 1
    - Costa del Sol : 1
    etc.

    -> c'est à dire :
    1) extraire tous les tags de toutes les offres que je veux afficher
    2) compter les tags

    J'ai donc bien une requête qui doit extraire les offres et leurs tags respectifs : "select distinct o from Offre as o left join fetch o.tag as tag".
    Sur la base de cette requête, je devrais pouvoir placer un count quelque part me permettant de récupérer une liste de tags et leur nombre respectif.
    Ben là j'y arrive pas.

    J'ai essayé avec HQL, avec Criteria, je ne parviens pas à constituer une liste disposant de 2 colonnes : tags et nbTags que je pourrai ensuite envoyer dans ma JSP pour affichage.

    Voilà. J'arrête de vous embêter. En tout cas, merci d'avoir pris le temps de regarder mon problème et encore une fois toutes mes excuses pour l'absence de réponse parce que c'est hyper-chiant les gens comme moi

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Citation Envoyé par Lovegiver Voir le message
    "select distinct o from Offre as o left join fetch o.tag as tag".
    Salut.
    Déjà de là,même si tu places un COUNT tu exclus la possibilité d'avoir le nombre exact qu'un tag existe dans tes offres.Puisque ta requête va exclure les doublons.

    Citation Envoyé par Lovegiver Voir le message
    J'ai essayé avec HQL, avec Criteria
    Quand il s'agit des requêtes de type CUD(Create,Update et Delete) un ORM est parfait mais loin de l'être pour celles de type R(Read) surtout complexes.Le mieux est d'utiliser les requêtes natives.

  6. #6
    Membre confirmé Avatar de freddou17
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2013
    Messages
    341
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2013
    Messages : 341
    Points : 566
    Points
    566
    Par défaut
    lu,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select o.tag.name, count(o) from Offre group by(o.tag.name)
    ça donne quoi?

    Edit:

    Quand il s'agit des requêtes de type CUD(Create,Update et Delete) un ORM est parfait mais loin de l'être pour celles de type R(Read) surtout complexes.Le mieux est d'utiliser les requêtes natives.
    un peu rapide comme raccourci, j'ai des read en hql qui sont assez complexes...

    ++
    "Aucun de nous ne sait ce que nous savons tous, ensemble."
    Lien vers mon appli Funcash n'hésitez pas à donner votre avis

  7. #7
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Citation Envoyé par freddou17 Voir le message
    un peu rapide comme raccourci, j'ai des read en hql qui sont assez complexes...++
    Rapide aussi concernant la performance et je n'ai nulle part dit que c'est impossible en HQL mais de préférence utiliser une requête native.Perso les requêtes complexes j'en ai en JPQL mais si je dois faire une requête avec des fonctions d'agrégation et jointures je passe par les requêtes natives.
    Citation Envoyé par freddou17 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select o.tag.name, count(o) from Offre group by(o.tag.name)
    Je crois que t'as oublié l'alias dans la clause FROM .

  8. #8
    Membre du Club Avatar de Lovegiver
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2015
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2015
    Messages : 81
    Points : 57
    Points
    57
    Par défaut
    Si je fais ça :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Query query = session.createQuery("select o.etiquettes from Offre as o");
      List<?> mots = query.list();
      
      //IMPRESSION POUR CONTROLE
      System.out.println("Nombre de mots = " + mots.size());
    	for(Object o:mots){
    	  System.out.println("mot : " + o.toString());
    	}
    j'obtiens ça :

    Hibernate: select motcle2_.id_MotCle as id_MotCl1_9_, motcle2_.motCle as motCle2_9_ from offre offre0_ inner join offre_motcle etiquettes1_ on offre0_.id_Offre=etiquettes1_.id_offre inner join motcle motcle2_ on etiquettes1_.id_motCle=motcle2_.id_MotCle
    Nombre de mots = 62
    mot : Luxe
    mot : Paris
    mot : Gastronomie
    mot : France
    mot : Climatisation
    mot : Famille
    mot : Piscine
    mot : France
    mot : Famille
    mot : Petit prix
    mot : France

    --> A ce stade, il me reste à grouper les tags et à les dénombrer, soit en fait la requête que je cherche désespérément...

    Si j'introduis count ou group by, j'ai des erreurs de syntaxe.
    Honnêtement, j'applique ce que je lis ici donc je ne vois pas de quelles erreurs on parle :

    ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_0_0_, count(offre0_.id_Offre) as col_1_0_, motcle2_.id_MotCle as id_MotCl' at line 1

    Par exemple, ça ça ne fonctionne pas :

    • select o.etiquettes from Offre as o group by o.etiquettes
    • select o.etiquettes from Offre as o group by (o.etiquettes)
    • select o.etiquettes, count(o) from Offre as o


    Voilà où j'en suis.
    C'est un problème qui a l'air tout bête mais ça me rend dingue.

    Merci pour votre aide.

  9. #9
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Citation Envoyé par Lovegiver Voir le message
    select o.etiquettes from Offre as o
    Attends etiquettes est une propriété de offre?puisque cette requête select distinct o from Offre as o left join fetch o.tag as tag montre que c'est sur 2 entités que tu travailles.

  10. #10
    Membre du Club Avatar de Lovegiver
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2015
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2015
    Messages : 81
    Points : 57
    Points
    57
    Par défaut
    Voici un extrait de ma classe Offre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @ManyToMany
    	@JoinTable(
    		name="offre_motcle",
    		joinColumns=@JoinColumn(name="id_offre"),
    		inverseJoinColumns=@JoinColumn(name="id_motCle"))
    	private Set<MotCle> etiquettes;
    -> "etiquettes", attribut de Offre, est un tableau de MotCle, une autre classe

    Comme je suis dans le cadre d'une relation ManyToMany sans attribut, j'ai une entité intermédiaire que j'ai appelée "offre_motcle" et qui contient :
    • un ID
    • la FK de Offre
    • la FK de MotCle



    Du coup, le "o.tag.name" écrit par freddou17 pour synthétiser ce qu'on se disait, correspond en réalité à o.etiquettes.motCle avec :
    • o l'alias de la classe Offre
    • etiquettes un attribut de Offre qui est un Set<MotCle>
    • motCle qui est le mot à proprement parler et qui est un attribut de la classe "MotCle" comme tu peux le voir ci-dessous

    :

    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
      @Entity
      @Table(name="motcle")
      public class MotCle {
    
    	/**
    	 * Primary Key du Mot-clé
    	 */
    	@Id
    	public int id_MotCle;
    	
    	/**
    	 * Le mot-clé
    	 */
    	@Column
    	private String motCle;
    	...

    Si j'ai bien compris la littérature, je n'ai pas besoin d'interroger directement l'entité intermédiaire offre_motcle parce qu'elle ne porte aucun attribut.
    Dans mes requêtes je m'attache donc à n'interroger que les classes Offre et MotCle.

    Mais là manifestement, je dois compter en plus avec des erreurs de syntaxe que je ne m'explique pas !

  11. #11
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2014
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 352
    Points : 349
    Points
    349
    Par défaut
    Salut.
    Essaie ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT m.motCle,COUNT(m.motCle) FROM Offre o JOIN o.etiquettes m GROUP BY m.motCle;
    J'ai supposé que motCle représente tag(utilisé dans cette requête : select distinct o from Offre as o left join fetch o.tag as tag).

Discussions similaires

  1. [Débutant] Récupérer une liste d'objet avec leurs sous liste
    Par Oussema86 dans le forum Linq
    Réponses: 1
    Dernier message: 18/01/2016, 13h55
  2. Réponses: 6
    Dernier message: 18/09/2013, 19h13
  3. Stocker une liste d'objets personnalisés dans les settings
    Par laville dans le forum Général Dotnet
    Réponses: 12
    Dernier message: 13/12/2007, 11h14
  4. Récupérer une liste d'objets via DynaForm
    Par vinceLeBarbare dans le forum Struts 1
    Réponses: 2
    Dernier message: 14/10/2007, 23h09
  5. [AJAX] Récupérer une liste d'objet d'un flux RSS en JSON
    Par Tavarez59 dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 07/10/2007, 01h10

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