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 :

Question pour une requête sur plusieurs tables/objets


Sujet :

Hibernate Java

  1. #41
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    comme je l'ai dit, tu va récupérer un List<Object[]> avec çà, pas un List<Personne>, ca fait toute la différence.

    Je vois pas en quoi ma proposition bafouerais le principe MVC, au contraire, avec ton système, si t'as une donnée à afficher en plus, t'es obligé de passer par le code pour changer ta query hibernate et inclure la donnée manquante. Donc tu as bien pollution de ton modèle par les spécificités de la vue.
    bon tu peux toujours rajouter une couche dans ton bean qui prend une List<Personne> et te filtre toutes les données, de toutes facons, c'est à toi de voir.

  2. #42
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 142
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    comme je l'ai dit, tu va récupérer un List<Object[]> avec çà, pas un List<Personne>, ca fait toute la différence.
    Oui... J'ai déjà été confronté à ce problème.
    Ce que tu peux faire, c'est boucler sur les résultats, et de peupler dynamiquement un Set.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Set<Personne> personnes = new HashSet<Personne>();
    for(Object[] o : myResult){
        personnes.add(o[0]);
    }
    return personnes;

  3. #43
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Là, je vous ai donné un sous exemple, mais je vais avoir à construire une requête avec 5 niveaux.
    Donc peupler à chaque fois une liste, ça va être lourd ...

    Ma requête hibernate me renvoit ce que je veux.
    Seulement si la seconde requête renvoit la même personne (soit, le niveau le plus haut), cet objet n'est pas reconstruit puisqu'il est en mémoire.

    Y a-t-il un moyen de forcer le rechargement de l'objet ?

  4. #44
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    non, puisque, de fait, l'objet est le même! Tu peux éventuellement faire un session.refresh(objet), mais ca ne sert que pour les cas où la base de donnée à changé depuis la dernière fois, en dehors de la session.

    Hibernate fait normalement ceci:


    - création d'une requete SQL à partir de ton HQL
    - exécution de cette requete
    - récupération des données et peuplement, éventuellement partiel, de la structure objet a partir de ces donnée (tout dépend des stratégies utilisées, la requete peut avoir retourné des objet complet ou juste des ids, mais ca change rien au code appelant)
    - éventuellement, nouvelles requetes HQL pour terminer de peupler tes objet pour les propriétés / relations où le lazy=false
    - Renvoi à l'appelant de la liste "Personne"

    L'appelant explorer une propriété ou relation d'un des objet Hibernate
    - le proxy hibernate vérifie que la propriété / relation a été initialisé. Si pas, il effectue les requetes SQL nécessaire que pour remplir l'objet. Si la session est fermée, une lazyloadingexception est lancée.
    - le proxy renvoie la valeur demandée.


    La première partie ce fait lors de ta requete, la deuxième, dans ton cas, au sein de ton JSP


    Donc, pour rendre les chose claires. Si la requete 1 doit renvoyer les personnes X et Y ET que la requete 2 doit aussi renvoyer les personnes X et Y, alors l'affichage dans ton jsp de ces deux listes de personne devrait être identique.

  5. #45
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Merci pour ces explications, c'est effectivement ce qu'il se passe, je pense ...
    En tous cas, ça y ressemble beaucoup !

    Est-ce que sans passer par Hibernate, je pourrais obtenir plus facilement ce que je souhaite ?

  6. #46
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Pour le moment, un "session.clear();" me permet de vider la session et donc hibernate va reconstruire à chaque l'objet selon ma recherche.
    Ca a au moins le mérite de me donner ce que je veux.

    Sinon, petite question subsidiaire : c'est possible d'utiliser plusieurs utilisateurs de BDD avec Hibernate ?

  7. #47
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    non, mais tu peux avoir plusieurs sessions active en meme temps.

    PS: j'ai aps compris en quoi recharger depuis la db donne ce que tu veux, puisque normalement a moins que t'aie un mapping raté, ce doit donner le même résultat tes requetes HQL, qu'il y aie ou non des données dans la session! Sinon t'as une méchante inconsistance quelque part

  8. #48
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Pourquoi je recharge depuis la DB ?

    Tout simplement pour obtenir l' "arborescence" souhaitée.

    Ainsi, avec ma requête et le paramètre idAnim = 1, il renvoie la personne 111 avec l'événement 11 qui a pour anim 1

    Ensuite, si je fais une requête avec idAnim = 2, il renvoie la personne 111. Et comme il l'a déjà chargée, il ne va pas faire d'autres requêtes dans la base pour continuer à construire l'objet. Il me retourne directement l'objet qu'il a stocké précédemment.

    Or, j'aimerais qu'il me renvoie la personne 111 avec l'événement 22 qui a pour anim 2 ...


    Donc le vidage de ma session me permet d'obtenir ce que je veux !

  9. #49
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    comem déjà dit, il doit te renvoyer dans les deux cas la personne 111 avec deux évènements: 11 et 22 à moins que t'ai raté ton mapping Y a pas re raison que personne.evenements ne contienent qu'un seul élément quand la DB contient deux valeurs Si t'es content tant mieux, mais je signale juste que c'est pas le comportement normal d'hibernate et que tu risque de revenir plus tard avec ce problème.

  10. #50
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Y a pas re raison que personne.evenements ne contienent qu'un seul élément quand la DB contient deux valeurs
    Suivant ma jointure, y'a une raison !
    Enfin, j'ai trouvé une solution, c'est le principal !

  11. #51
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    si tu parle de la jointure HQL, justement non, le contenu de personnes.evenements doit être indépendant de cette jointure (c'est quand meme un des garantie que donne hibernate). Si tu parle de ton modèle de base de donnée, je m'inquiéterait d'avoir une relation qui change comme çà au fil du temps sans que la db ne change


    La j'avoue, je suis un peu largué sur le comportement de ta db et ton modèle

  12. #52
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    C'est pas la relation qui change !

    Mais avec une jointure et un filtre sur cette jointure, c'est quand même normal que ma requête ne me retourne pas autant d'enregistrement que sans filtre et avec une jointure externe !

  13. #53
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    alors soit on parle pas la meme langue soit j'ai vraimentdu mal a me faire comprendre
    avec hibernante, peut importe la requete que tu a utilisé pour récupérer un objet "Personne", quand tu fera personne.getEvenements() (ce que fait ton jsp via les boucle for) tu aura toujours la même liste d'évènement. autrement dit, que je fasse:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT p  From Personne AS p  left join fetch p.evenements AS e  left join fetch e.animateurs a WHERE a.idAnim = '11'
    qui te retourne la Personne 111

    ou que tu fasse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT p  From Personne AS p where p.id=111
    qui te retourne aussi la Personne 111

    ou encore
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT p  From Personne AS p  left join fetch p.evenements AS e  left join fetch e.animateurs a WHERE a.idAnim = '22'
    qui te retourne aussi la personne 111

    quand tu fera personne.getEvenements() tu aura toujours la même liste d'évènements, quel que soit le nombre d'évènements retournés par la requete HQL initiale puisque, c'est là la magie d'hibernate, tes collections sont indépendante de la requete initiale et il va remplir correctement avec les selects nécessaire la List<Evenement> (ou le Set ou le Bag peu importe ce que tu as choisi) au moment opportun, pour que justement cette liste soit complète et reflète la base de donnée, non ta requete HQL initiale.

    Et si c'est pas le cas, c'est que t'as fait une bidouille quelque part dont je suis pas au courant, ou que t'as un sérieux problème avec ton mapping quelque part.

  14. #54
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Peut-être ai-je un problème.

    Toujours est-il que ça me rend ce que je veux, alors que je galèrais pour trouver ...

    Je vais donc laisser comme ça, puisqu'apparemment, il n'y pas de moyen "plus propre" pour faire ce que je voudrais avec Hibernate.

    Sinon, si j'ai un peu de temps plus tard, je verrai pour faire directement en SQL.

  15. #55
    Membre éclairé
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Par défaut
    Bon, effectivement, vous aviez raison ...

    Je reviens vers vous car les performances de ma partie Hibernate plombent littéralement mon application ...
    Etant donné qu'à chaque fois, Hibernate requête dans la base, ça met un temps fou, car j'ai des millions d'enregistrements en base.

    Il faut donc que je trouve un moyen plus clair pour faire mes restrictions comme cela, Hibernate mettra du temps à charger la base complète mais j'aurai des temps de réponse beaucoup plus intéressants (c'est ce que j'espère).

    Je vous écoute donc ...

Discussions similaires

  1. Requête sur plusieurs tables/objets
    Par pontus21 dans le forum Hibernate
    Réponses: 2
    Dernier message: 29/04/2009, 15h43
  2. Réponses: 2
    Dernier message: 12/01/2008, 15h57
  3. Aide pour une requête sur deux tables
    Par Andry dans le forum Développement
    Réponses: 2
    Dernier message: 05/11/2007, 08h14
  4. Aide pour une requête sur deux tables
    Par Andry dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 05/11/2007, 08h14
  5. faire une requête sur plusieurs tables
    Par julien.63 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 16/08/2006, 23h58

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