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 :

Libération de collection LAZY


Sujet :

Hibernate Java

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Septembre 2007
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Libération de collection LAZY
    Bonjour,

    Ma question peut se résumer ainsi :

    Comment réinitialiser les Collection LAZY quand on as plus besoin des données qu'elles contienent mais que l'on souhaite quand même pouvoir eventuellement les recharger par la suite de façon transparente via le mechanisme Lazy.

    Je développe une application qui parcourt une arborescence de taille importante en chargeant chaque branche de façon LAZY.
    A l'ouverture de mon application je crée une Session hibernate que je clos à la sortie de l'application.
    Cela fonctionne très bien, mes objets sont effectivement chargés à la demande de façon transparente dans mon code applicatif (traces SQL hibernate à l'appui)

    Par contre actuellement je n'ais pas trouvé de moyen propre pour libérer les objets chargés via une relation OneToMany lazy.

    Un .clear() brutal sur la collection lazy fera qu'elle ne pourra plus jamais être rechargée de façon transparente.

    Le seul moyen que j'ai trouvé actuellement est de faire un refresh() sur l'entité propriétaire de la collection lazy ce qui semble réinitialiser toutes les relations OneToMany Lazy que l'entité possède.

    Je trouve cela un peu violent d'être obligé de passer par la base pour pouvoir libérer des objets de mon cache

    N'y as t'il pas un mechanisme hibernate qui permette de réinitialiser les collections Lazy sans être obligé de passer par la base ?

    Merci d'avance pour votre aide.

  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
    Désolé mais je ne comprends pas bien ce que tu cherches à faire.
    Si tu veux vider ton cache de session, tu peux faire un session.clear.
    Du coup, quand tu chargeras tes objets, ils seront pris dans la base.

    Après, le coup de garder une session ouverte de l'ouverture à la fermeture de l'application ne me semble pas être une super idée.
    A moins de faire attention à la taille de celle-ci et de la vider au fur et à mesure, tu risques de la faire "exploser" si tu manipules beaucoup de données.
    Il est d'ailleurs généralement conseillé d'avoir une session de durée de vie assez courte.

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Septembre 2007
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci de ta réponse.

    En gros , je souhaite afficher une arborescence, chaque branche de l'arborescence est chargée de façon LAZY.

    Donc quand on déplie un objet dans l'UI la session hibernate va automatiquement chercher ses fils et je les affiche.
    Jusque la pas de problème.

    Par contre, effectivement si je fais comme cela mon cache ne peut que grossir ce qui finira inévitablement par créer des problèmes.

    Mon souhait est donc de libérer les objets quand l'utilisateur replis certains noeuds de l'arborescence (ou garbage collecter les noeuds repliés depuis longtemps).
    Pour cela le seul moyen que j'ai trouvé actuellement est de :
    * faire un evict cascadé sur l'objet replié
    * de dissocier manuellement l'objet replié de ses fils
    * d'appeller le garbage collector
    * de faire un refresh sur l'objet replié pour le réassocier à la session courrante.

    Cela fonctionne et par la suite je peu redéplier le noeud ce qui rechargera à nouveau ses fils de façon lazy.

    Mon problème est l'étape de refresh, je sais que l'objet n'a pas été modifié pourquoi devrais-je faire un appel en base dans le seul but de le réassocier à la session courrante ? n'y as t'il pas une fonction inverse à evict ? Mon but est seulement de retourner à l'état avant que les fils soient chargés dynamiquement.

  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
    Tu as les méthodes lock et merge pour réassocier un objet à une session.
    http://www.hibernate.org/hib_docs/v3...e/Session.html

    Tu peux aussi procéder autrement.
    Tu pourrais ouvrir et fermer ta session à chaque groupe d'actions à ta base.
    Pax exemple, quand tu cliques sur un noeud de ton interface, tu ouvres une session, charge les données que tu veux afficher, et ferme ta session.
    Au moins, plus de problème de taille de session, même si ça complexifie les opérations de chargement.

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Septembre 2007
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merge est une opération qui interragie avec la base.
    Dans mon cas si je merge après avoir détaché les fils cela les supprimeras dans la base.

    Si je change de session à chaque ouverture d'objet dans l'interface.
    Il faudra que je récupère les fils en 2 étapes :
    1) réassocier le noeud père à la nouvelle session via un load() ou un refresh() ou eventuellement un merge()
    Cette opération fera un appel en base qui est pour moi inutile car je sais que l'objet dans mon cache est à jour.
    2) réellement récupérer les fils via l'accesseur déclaré Lazy.

    On est obligé de faire un appel en base supplémentaire.

    On peu se passer de l'étape de rechargement du noeud père en faisant directement une query pour obtenir les fils mais alors le mechanisme lazy n'est pas du tout utilisé et je ne vois pas bien l'interrèt d'hibernate

    Enfin même si un objet est détaché de la session il n'est pas forcément garbage collecté par java, il faut qu'il ne soit plus référencé nulle part. En l'occurence il faut le détacher de son père. Si on fait cela le mechanisme de merge qui semble en effet être préconisé détectera un changement et désassociera les fils de leur père en base.

Discussions similaires

  1. Comment bien gérer les Lazy Collection ?
    Par ZouBi dans le forum Persistance des données
    Réponses: 7
    Dernier message: 29/11/2012, 09h39
  2. Charger une collection Lazy
    Par Faiche dans le forum JPA
    Réponses: 7
    Dernier message: 07/09/2009, 16h08
  3. Grosses collections et lazy : besoin d'explication
    Par waflyx dans le forum Hibernate
    Réponses: 3
    Dernier message: 10/03/2008, 14h43
  4. Hibernate 3.2.2 et lazy collection
    Par Fr@ncky dans le forum Hibernate
    Réponses: 2
    Dernier message: 29/06/2007, 11h30
  5. [Lazy Loading] Exception à la lecture d une collection
    Par julienOriano dans le forum Hibernate
    Réponses: 4
    Dernier message: 04/06/2007, 11h56

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