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 :

choix de stratégies en lazy-loading


Sujet :

Hibernate Java

  1. #1
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut choix de stratégies en lazy-loading
    Bonjour à tous,

    Encore une énième question sur le chargement lazy dans hibernate...
    J'utilise Hibernate 3.2.5.ga dans une application basé sur un framework type netbeans, eclipse me permettant de partitionner mon application en différents modules.
    Dans mon application, je charge dès le démarrage certaines données primordiales. Une donnée particulière possède une liste d'éléments qui peut facilement dépasser les 10000 éléments. J'ai fait donc fait en sorte que le chargement de ces éléments soit différé en effectant 'extra lazy' .

    Ces données peuvent être visualisées dans un tableau et donc, je souhaite faire en sorte que la tentative de récupération de l'élément à l'index 20 provoque l'éxécution d'une requete permettant de charger l'objet correspondant s'il ne l'est pas déjà.
    Le problème, c'est donc qu'il faut que j'englobe, en gros, les appels aux méthodes : getRowCount, etc... de mon modèle de table dans une session. Tant qu'a faire, si j'ai bien compris, il faut que si la session utilisé est nouvelle, il faut que je réattache mon objet contenant la liste à cette nouvelle session, et idéalement, utiliser la même session ce qui m'évitera tout le processus de réattachement.

    L'application en question est un client lourd, donc j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hibernate.current_session_context_class=thread
    J'ai lu a différents endroits que le couplage d'hibernate avec Spring était souvent la solution à ce genre de problèmes mais j'aimerais en savoir un peu plus sur les points suivants :
    • existe t-il une autre façon de résoudre le problème sans plomber mon modèle de table par la création de session inutile?
    • ne connaissant que très peu spring, existe t-il un tutorial permettant de mieux comprendre comment réaliser ce que je viens de citer?
    • c'est certainement une mauvaise compréhension de ma part mais j'aimerais savoir si lazy="extra" est imcompatible avec l'attribut batch-size? (question idiote ).
    D'autres part, si c'est vraiment vers cette solution que je dois m'orienter, cela signifie que au fur et à mesure que je vais visualiser les éléments de ma table, je risque certainement d'avoir des effets de lenteur (au moins jusqu'à ce que tous les éléments soient chargés ). Y'a t'il une solution à cette conséquence?
    bref, j'aimerais avoir différents avis sur ce genre de problème.

    xixi.

  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 peux aller voir ce thread, peut-être que tu y trouveras quelque chose:
    http://www.developpez.net/forums/sho...d.php?t=464113

    Pour ce qui est du chargement dans une application Swing, je ne touche pas à la session Hibernate dans mon modèle.
    La sesssion n'est utilisée qu'au sein d'une couche de service qui renvoie les données à afficher.
    Quand j'ai trop de données à afficher, je fais un filtre pour les réduire, car à mon sens, un tableau à 10000 valeurs est inutilisable.
    Je charge uniquement les données qui m'intéressent via des fetch join.
    Dans mon cas, ça me convient.

    Christian Bauer (il me semble), un des membres de l'équipe Hibernate, avait écrit sur son blog, un article intéressant concernant l'utilisation d'Hibernate pour un client lourd. Je vais essayer de retrouver le lien.

  3. #3
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    merci pour les infos. ca serait effectivement intéressant d'avoir le lien vers cette doc hibernate dans un client lourd...

  4. #4
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    Visiblement, va falloir que je me mette a Spring...

    une autre question qui découle de mon problème, si je me débrouille avec spring via de la programmation par aspect, cela signifie que je risque de créer une session à chaque fois même les fois où ce que je chercherai à accéder aura été initialisé précédemment... Y'a t-il un moyen d'éviter ca?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 83
    Points
    83
    Par défaut
    Un conseil: Spring est un excellent framework pour les personnes qui maîtrisent bien Hibernate, et il est excessivement piégeux pour les autres (et quand je dis piégeux, je suis vraiment gentil).

    Il ne répondra d'ailleurs en rien à ton problème. Une solution efficace qui s'offre est l'uilisation des requête HQL et la pagination pour extraire tes données au moments ou tu en as besoin....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    List maListe = session.createQuery("Requete qui fetche les 10000 enregistrements").setFirstResult(X).setMaxResult(20).list()
    Tu incrémentes X au besoin...
    Attention, le comportement de ce type de truc est différent en fonction de ta base de données

  6. #6
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    en fait, la table qui affiche mes éléments gère déjà la pagination graphique...
    est-ce que dans ce cas, utiliser des requête HQL en paginant ne revient pas à initialiser correctement le batch-size sur ma collection et laisser hibernate faire au besoin ?

  7. #7
    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
    J'ai retrouvé le lien :
    http://in.relation.to/Bloggers/HibernateAndSwingDemoApp

    On peut même télécharger les sources.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 83
    Points
    83
    Par défaut
    Je ne comprends pas ce que tu veux dire par

    Citation Envoyé par xixi31 Voir le message
    en fait, la table qui affiche mes éléments gère déjà la pagination graphique...
    au besoin ?

    est-ce que dans ce cas, utiliser des requête HQL en paginant ne revient pas à initialiser correctement le batch-size sur ma collection et laisser hibernate faire
    Ne ferais tu pas l'amalgame entre batch-size et la taille du curseur utilisé par le driver ? Je ne pense pas que le batch-size t'aide à résoudre ton problème (voire je suis sur du contraire)

    le batch-size:

    Suppose que Tu aies une entité A qui possède une collection d'entité B (association LAZY, et paramétrée avec un batch-size=3).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Session session = sf.open();
    A a1 = session.get(A.class,1);
    A a2 = session.get(A.class,1);
    A a3 = session.get(A.class,1);
    A a4 = session.get(A.class,1);
    A a5 = session.get(A.class,1);
    a3.getB().getProperty();
    La requête générée par la dernière ligne qui charge les éléments B pour a3 va remonter simultanément les élements B associés à 3 autres éléments A qui sont dans la session (lesquels, je ne sais pas) et donc initialiser les collections de B de a1, a4 et a5 par exemple...

    Voila le rôle du batch-size
    Enfin, c'est ce que j'en ai compris...

  9. #9
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    je veux dire que ma table intégre une gestion de pages, elle peut ne montrer que 10 éléments au total mais l'utilisateur a accès a deux boutons pour respectivement aller à la page précédente ou aller à la page suivante. ce que je me disais donc, c'est que si je mets l'association en lazy="extra", hibernate me chargerais les données que la table permet de visualiser au besoin (autrement dit, mes premiers 10 éléments).
    Je n'ai pas compris ton exemple, mais d'après le peu de connaissance que j'ai sur hibernate, je crois que tes références a1, a2, a3, a4, a5 vont pointer vers le même objet, non?
    Je suis d'accord sur le principe du batch-size. dans mon cas, peut-être cela pourrait-il m'arranger que, lorsque hibernate détecte le besoin de charger l'élément placé à la position 5, il en profite pour charger également le 6, 7, 8, 9 et 10 par exemple. J'ai l'impression de passer à travers, non !!

    merci pour vos réactions. merci fr1man pour le lien, je vais lire ca avec beaucoup d'intéret.

    xixi

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 83
    Points
    83
    Par défaut
    Code :


    oups... sacré copié collé !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Session session = sf.open();
    A a1 = session.get(A.class,1);
    A a2 = session.get(A.class,2);
    A a3 = session.get(A.class,3);
    A a4 = session.get(A.class,4);
    A a5 = session.get(A.class,5);
    a3.getB().getProperty();
    La requête générée par la dernière ligne qui charge les éléments B pour a3 va remonter simultanément les élements B associés à 3 autres éléments A qui sont dans la session (lesquels, je ne sais pas) et donc initialiser les collections de B de a1, a4 et a5 par exemple...

    Voila le rôle du batch-size


    Citation Envoyé par xixi31 Voir le message
    je veux dire que ma table intégre une gestion de pages, elle peut ne montrer que 10 éléments au total mais l'utilisateur a accès a deux boutons pour respectivement aller à la page précédente ou aller à la page suivante. ce que je me disais donc, c'est que si je mets l'association en lazy="extra", hibernate me chargerais les données que la table permet de visualiser au besoin (autrement dit, mes premiers 10 éléments).
    Je n'ai pas compris ton exemple, mais d'après le peu de connaissance que j'ai sur hibernate, je crois que tes références a1, a2, a3, a4, a5 vont pointer vers le même objet, non?
    Je suis d'accord sur le principe du batch-size. dans mon cas, peut-être cela pourrait-il m'arranger que, lorsque hibernate détecte le besoin de charger l'élément placé à la position 5, il en profite pour charger également le 6, 7, 8, 9 et 10 par exemple. J'ai l'impression de passer à travers, non !!

    merci pour vos réactions. merci fr1man pour le lien, je vais lire ca avec beaucoup d'intéret.

    xixi

  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
    Si j'ai bien compris, tu n'affiches que 10 éléments à la fois dans ton tableau et les autres sont accessibles par une action de l'utilisateur.
    Je suppose que cette action va chercher les 10 prochains éléments via une requête.
    Dans ce cas là, tu fais les choses de la bonne manière.

  12. #12
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    J'ai un peu des doutes sur ma manière de faire, je n'ai pas encore effectué de tests mais je me dis que aller rechercher les infos en base sur un getValueAt() du modèle de table (en appliquant de l'AOP via Spring), ca va pas rendre l'application très dynamique. Je vais essayer et on verra ce que ca donne.

    Merci en tout cas pour vos commentaires.

  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
    En fait, je ne pensais pas faire ça dans le getValueAt().
    Je pensais, suite à l'action de l'utilisateur, faire appel à un service qui reconstruit le modèle de ton tableau avec les 10 éléments à afficher.
    Je suis ok, que du coup, tu fais sans cesse des appels à la base, mais au moins tu ne charges que ce dont tu as besoin à un instant T.

    Tu pourrais aussi dans ton modèle stocker les 10 éléments courants, les 10 précédents et les 10 suivants.
    Comme ça, quand l'utilisateur veut afficher les suivants, ou précédents, ils sont déjà en mémoire et l'affichage sera rapide.
    A voir si c'est réalisable.

  14. #14
    Membre averti Avatar de xixi31
    Inscrit en
    Juin 2005
    Messages
    423
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Juin 2005
    Messages : 423
    Points : 414
    Points
    414
    Par défaut
    effectivement, j'ai cette autre solution aussi.

    ce qui m'embete, c'est que l'utilisateur peut avoir la visualisation complète des données (la pagination du module graphique peut-être activé ou non par l'utilisateur) mais là, c'est un autre problème (plus lié au fonctionnel). C'est bête mais étant donné les outils similaires sur le marché, je crois que je ne peux pas faire autrement que charger l'ensemble des données dès le démarrage. Merci en tout cas pour vos remarques qui ont pu m'apporter une meilleure compréhension d'hibernate (y'a encore du boulot ).
    Merci à vous deux.

    Mon post de départ n'étant pas vraiment une question mais plus une demande de réactions, je met tout ca en résolu.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par xixi31 Voir le message
    effectivement, j'ai cette autre solution aussi.

    ce qui m'embete, c'est que l'utilisateur peut avoir la visualisation complète des données (la pagination du module graphique peut-être activé ou non par l'utilisateur) mais là, c'est un autre problème (plus lié au fonctionnel). C'est bête
    Moauip..; enfin, fonctionnellement, afficher une page avec 10000 éléments ne me semble pas adapté à des bonne habitudes d'ergonomie !

    Mon post de départ n'étant pas vraiment une question mais plus une demande de réactions, je met tout ca en résolu.
    bon courage ;-)

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

Discussions similaires

  1. spring2 hibernate3 : lazy loading
    Par fxonline dans le forum Hibernate
    Réponses: 9
    Dernier message: 10/02/2007, 18h56
  2. Lazy loading sur component
    Par El Saigneur dans le forum Hibernate
    Réponses: 2
    Dernier message: 03/11/2006, 10h30
  3. Lazy loading et fermeture de session hibernate
    Par BRAUKRIS dans le forum Hibernate
    Réponses: 3
    Dernier message: 20/07/2006, 13h08
  4. [hibernate] problème pour desactiver le lazy loading
    Par agougeon dans le forum Hibernate
    Réponses: 2
    Dernier message: 14/03/2006, 11h20
  5. [HIBERNATE 3]Lazy loading
    Par SEMPERE Benjamin dans le forum Hibernate
    Réponses: 11
    Dernier message: 08/02/2006, 22h40

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