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 :

LazyInitializationException encore une fois


Sujet :

Hibernate Java

  1. #1
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut LazyInitializationException encore une fois
    Bonjour,

    après avoir fouillé la doc de référence et les forums je n'ai pas trouvé ma réponse, donc je poste:

    Dans mon application (java + jsf+ spring + hibernate) il y a un objet (CGE) du modèle qui contient les collections de tous les autres objets.
    Sur 5 options de menu , deux sont incompatibles et j'obtiens une LazyInitializationException quand je passe de l'un à l'autre, ce qui ne devrait pas.
    Disons que pour simplifier dans mon option A, le CGE utilise les collections a, b, et c et dans l'option B il utilise les collections a, d et e.
    Quand je vais de A vers B, il se plaint de 'no session or session closed' pour la collection d et e, et vice versa.

    J'ai essayé lazy=true et lazy=false, rien n'y fait.

    C'est quand même gênant de demander à mon utilisateur de se reconnecter entre deux options de menu !
    Quelqu'un a une idée ?

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2010
    Messages : 54
    Par défaut
    je suppose que tu déconnecte la session en fin de requete? Si oui, le plus simple à faire, c'est de prendre ton option de menu, et, avant de l'explorer, de faire un merge pour le reconnecter à la nouvelle session, via


    menu = session.merge(menu);

    L'autre option est de mettre tes entrée de menu en request scope pour qu'elles soient reconstruites à chaque connection

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Par défaut
    J'ai essayé lazy=true et lazy=false, rien n'y fait.
    L'attribut lazy sur tes collections fonctionnera uniquement si ton objet CGE est une entité Hibernate.


    Disons que pour simplifier dans mon option A, le CGE utilise les collections a, b, et c et dans l'option B il utilise les collections a, d et e.
    Si tes options de menu sont toutes interdépendantes et que la volumétrie des objets derrière n'est pas importante, t'embête pas et charge les en une seule fois (le lazy ou une requête pourrait le faire).
    Ca rendra le traitement rapide (une seule requête) et le code sera simple.

    Dans le cas inverse, l'option du merge sur ton objet CGE (si c'est une entité de type Hibenate) peut faire l'affaire.
    Elle présente quand même l'inconvénient de faire autant d'appel en base que de collections non initialisées à charger.
    Sur une ou deux collections, aucun prob. Si il y en a + de 4 ou 5, ca peut se ressentir côté client.

  4. #4
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut le mapping initial
    merci pour vos contributions

    en fait hibernate mappe toutes les collections au lancement et bizarrement utilise deux sessions je ne sais pas ce qui provoque cela .
    Extrait du log de tomcat:

    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
    36
    37
    INFO: Server startup in 7379 ms
    2010-07-09 17:57:55,361 INFO [org.hibernate.cfg.Environment] - Hibernate 3.3.1.GA
    2010-07-09 17:57:55,366 INFO [org.hibernate.cfg.Environment] - hibernate.properties not found
    2010-07-09 17:57:55,370 INFO [org.hibernate.cfg.Environment] - Bytecode provider name : javassist
    2010-07-09 17:57:55,376 INFO [org.hibernate.cfg.Environment] - using JDK 1.4 java.sql.Timestamp handling
    2010-07-09 17:57:55,528 INFO [org.hibernate.cfg.Configuration] - configuring from url: file:/Users/mcollas/tom60/Dev/tomcat/webapps/esup-rendezvous/WEB-INF/classes/properties/dao/hibernate/hibernate-jdbc.cfg.xml
    2010-07-09 17:57:55,577 INFO [org.hibernate.cfg.Configuration] - Configured SessionFactory: null
    2010-07-09 17:57:55,673 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.structure.CGE -> V_RDV_CGE
    2010-07-09 17:57:55,704 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.etudiants -> V_RDV_ETUDIANT
    2010-07-09 17:57:55,704 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.gestionnaires -> RDV_PERSONNEL
    2010-07-09 17:57:55,704 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.tranchesReservees -> RDV_JOURSRESERVES
    2010-07-09 17:57:55,704 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.etapes -> V_RDV_ETAPE
    2010-07-09 17:57:55,705 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.etapesReservantes -> RDV_ETAPE
    2010-07-09 17:57:55,706 INFO [org.hibernate.cfg.HbmBinder] - Mapping class join: org.esupportail.rendezvous.domain.model.structure.CGE -> RDV_CGE
    2010-07-09 17:57:55,760 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.structure.Composante -> V_RDV_COMPOSANTE
    2010-07-09 17:57:55,761 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.Composante.etudiants -> V_RDV_ETUDIANT
    2010-07-09 17:57:55,781 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.structure.Etape -> V_RDV_ETAPE
    2010-07-09 17:57:55,861 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.EtapeReservante -> RDV_ETAPE
    2010-07-09 17:57:55,863 INFO [org.hibernate.cfg.HbmBinder] - Mapping class join: org.esupportail.rendezvous.domain.model.EtapeReservante -> V_RDV_ETAPE
    2010-07-09 17:57:55,906 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.intervenant.Etudiant -> V_RDV_ETUDIANT
    2010-07-09 17:57:55,908 INFO [org.hibernate.cfg.HbmBinder] - Mapping class join: org.esupportail.rendezvous.domain.model.intervenant.Etudiant -> RDV_ETUDIANT
    2010-07-09 17:57:56,013 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.ListEtudiants -> RDV_ETUDIANT
    2010-07-09 17:57:56,015 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.ListEtudiants.rendezVous -> RDV_ETUDIANT
    2010-07-09 17:57:56,024 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.agenda.Horaire -> RDV_HORAIRE
    2010-07-09 17:57:56,033 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.intervenant.Personnel -> RDV_PERSONNEL
    2010-07-09 17:57:56,039 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.agenda.TrancheFermee -> RDV_JOURSFERMETURE
    2010-07-09 17:57:56,047 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.agenda.TrancheReservee -> RDV_JOURSRESERVES
    2010-07-09 17:57:56,058 INFO [org.hibernate.cfg.HbmBinder] - Mapping class: org.esupportail.rendezvous.domain.model.ListJoursReserves -> RDV_JOURSRESERVES
    2010-07-09 17:57:56,060 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.ListJoursReserves.joursReserves -> RDV_JOURSRESERVES
    2010-07-09 17:57:56,060 INFO [org.springframework.orm.hibernate3.LocalSessionFactoryBean] - Building new Hibernate SessionFactory
    2010-07-09 17:57:56,061 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.horaires -> RDV_HORAIRE
    2010-07-09 17:57:56,062 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.rendezVous -> RDV_ETUDIANT
    2010-07-09 17:57:56,062 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.tranchesFermees -> RDV_JOURSFERMETURE
    2010-07-09 17:57:56,062 INFO [org.hibernate.cfg.HbmBinder] - Mapping collection: org.esupportail.rendezvous.domain.model.structure.CGE.joursReserves -> RDV_JOURSRESERVES
    2010-07-09 17:57:56,141 INFO [org.hibernate.connection.DriverManagerConnectionProvider] - Using Hibernate built-in connection pool (not for production use!)
    2010-07-09 17:57:56,141 INFO [org.hibernate.connection.DriverManagerConnectionProvider] - Hibernate connection pool size: 20
    2010-07-09 17:57:56,141 INFO [org.hibernate.connection.DriverManagerConnectionProvider] - autocommit mode: false
    il y a peut-être un rapport parce que les 4 dernières collections sont utilisées par cette option de menu qui plante si je l'utilise en 2ème.
    Est-ce qu'il y aurait des contraintes de taille qui oblige Hibernate à utiliser 2 sessionFactories ?

    Sinon pour les autres remarques j'utilise un hibernate dépendant de spring et jsf à l'intérieur d'un framework et beaucoup de choses échappent un peu à mon contrôle. par exemple je n'ai pas la main sur la sessionFactory d'Hibernate, ni pour l'ouvrir ni pour la fermer (ce serait trop simple).

    J'ai une autre interrogation: à quoi correspond ce paramètre ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Hibernate connection pool size: 20
    Si je l'augmente cela fait quoi ?

    oum

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2010
    Messages : 54
    Par défaut
    Citation Envoyé par oum Voir le message
    en fait hibernate mappe toutes les collections au lancement et bizarrement utilise deux sessions je ne sais pas ce qui provoque cela .
    Il crée les session que tu lui demande de créer. Si il a créé deux session, c'est que tu as fait deux appel à openSession
    Extrait du log de tomcat:
    Rien d'exceptionnel dedans, un démarrage d'hibernate tout ce qu'il y a de plus classique

    il y a peut-être un rapport parce que les 4 dernières collections sont utilisées par cette option de menu qui plante si je l'utilise en 2ème.
    Il y a deux manières d'éviter un lazyinitialisationexception sur une collection quand on objet hibernate est détaché. Soit définir la collection en lazy=false, soit de rattacher l'objet contenant la collection à une session avant de l'explorer.

    Est-ce qu'il y aurait des contraintes de taille qui oblige Hibernate à utiliser 2 sessionFactories ?
    Pourquoi utiliser 2 factories? Je n'en vois qu'une dans ton code

    J'ai une autre interrogation: à quoi correspond ce paramètre ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Hibernate connection pool size: 20
    Si je l'augmente cela fait quoi ?
    Ca augment le nombre de connections à la base de données que maintient le pool. Plus il y a des connections, plus tu peux avoir de session.


    Je ne connais pas à fond Spring, mais pour ton cas, tu gagnerais à mettre les données liées à hibernate en request scope et non pas en session scope.

  6. #6
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut
    merci Castorjoyeux pour ton aide.

    Si il a créé deux session, c'est que tu as fait deux appel à openSession
    il semble en effet que toutes les requêtes font appel à la même session ibernate, mais il y a un truc qui s'appelle batch qui doit faire appel à une autre sessionfactory

    Citation:
    J'ai une autre interrogation: à quoi correspond ce paramètre ?

    Code :
    Hibernate connection pool size: 20
    Si je l'augmente cela fait quoi ?

    Ca augment le nombre de connections à la base de données que maintient le pool. Plus il y a des connections, plus tu peux avoir de session.
    sais-tu le maximum qu'on peut mettre ? je peux monter à 60 ? Si c'est trop bas est-ce que je peux avoir des sessions(http) qui se mélangent entre elles ?

    je suppose que tu déconnecte la session en fin de requete? Si oui, le plus simple à faire, c'est de prendre ton option de menu, et, avant de l'explorer, de faire un merge pour le reconnecter à la nouvelle session, via


    menu = session.merge(menu);
    là je ne comprends pas très bien: tu parles de session hibernate ou http ?
    En fait on déconnecte jamais la session http sauf par time-out ou clic volontaire du client sur option de menu deconnexion. Et toute l'application est en scope session. pour tout réunitialiser.
    l'objet menu de ton exemple c'est une servlet ? ou un controleur appelé par servlet ?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2010
    Messages : 54
    Par défaut
    Citation Envoyé par oum Voir le message
    il semble en effet que toutes les requêtes font appel à la même session ibernate, mais il y a un truc qui s'appelle batch qui doit faire appel à une autre sessionfactory
    Le batch, c'est l'opération que fait hibernate lors du commit des changement ou des flush, ça fait partie de ta session. Hibernante ne crée pas de session de lui même, il les crée à la demande (voir la config de spring donc)

    sais-tu le maximum qu'on peut mettre ? je peux monter à 60 ? Si c'est trop bas est-ce que je peux avoir des sessions(http) qui se mélangent entre elles ?
    Les sessions http n'ont rien à voir avec hibernate. Quand il n'y a plus de connexions dans le pool, les demandes de nouvelles sessions hibernate sont mis en attente (arrêt du thread concerné) jusqu'à ce qu'une autre session soit fermée et donc libère une connexion.

    là je ne comprends pas très bien: tu parles de session hibernate ou http ?
    En fait on déconnecte jamais la session http sauf par time-out ou clic volontaire du client sur option de menu deconnexion. Et toute l'application est en scope session. pour tout réunitialiser.
    l'objet menu de ton exemple c'est une servlet ? ou un controleur appelé par servlet ?
    je parle de la session hibernate bien sur. L'objet menu dont je parle c'est celui que tu manipule là, celui qui déclenche l'exception quand tu explore sa collection :/

  8. #8
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut
    Bonjour CastorJoyeux,
    tu disais donc:
    Citation Envoyé par CastorJoyeux Voir le message
    je suppose que tu déconnecte la session en fin de requete? Si oui, le plus simple à faire, c'est de prendre ton option de menu, et, avant de l'explorer, de faire un merge pour le reconnecter à la nouvelle session, via


    menu = session.merge(menu);

    L'autre option est de mettre tes entrée de menu en request scope pour qu'elles soient reconstruites à chaque connection
    J'ai retrouvé dans le code des instructions qui ressemblent à ça. Dans la partie que j'ai rajoutée il n'y en avait pas. J'ai donc inséré ces merges chaque fois qu'il y avait modif dans les tables, et je crois que de toute façon avec tes explications c'était nécessaire. Malheureusement les lazyexception sont toujours là.

    J'en suis donc là:
    je prends une option de menu qui ouvre les tables a , b, c dans l'objet CGE.
    A chaque mise à jour, je fais un merge du menu.
    Je quitte l'option de menu pour aller sur l' autre qui entre dans la méthode enter, reprend le CGE du menu, fait un refresh de l'ensemble dans lequel hibernate repasse en revue toutes les tables et puis plus loin dans le traitement quand je veux rouvrir la table b par exemple hop: lazyexception :session closed!
    J'y perds mon latin (ou plutôt mon java)

  9. #9
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut detachedCriteria
    encore une question:
    parmi les requêtes il me semble (je ne les ai pas sous les yeux) que certaines utilisent des detachedCriteria plutôt que des criteria.
    Est-ce que cela pourrait expliquer les lazyexceptions ?

  10. #10
    oum
    oum est déconnecté
    Membre confirmé
    Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2006
    Messages : 56
    Par défaut resolu
    bonne nouvelle, j'ai résolu mon problème

    j'explique, au cas où cela serait utile à quelqu'un d'autre.
    Je précise que ce n'est pas moi qui ai développé l'appplication, j'ai seulement ajouté des fonctionnalités, donc il fallait que je comprenne ce que faisait le programme.
    L'erreur ne venait pas de la configuration xml, ni du mapping.
    L'idée de regarder du côté des merge de menu était bonne. [merci castorjoyeux ] J'ai tout repassé en mode debug.
    En fait quand la page jsp est chargée, les variables étaient correctement initialisées, mais après il faisait un reset et remettait tout à zéro pour reconstruire ses objets ensuite. Même en rajoutant un merge des menus, dans certains cas ça ne suffisait pas à reconstruire toutes les collections. J'ai donc ajouté un appel à ces collections au bon endroit pour les reconstruire.

    Ce bug m'a tout de même narguée pendant deux mois !


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

Discussions similaires

  1. encore une fois j'ai besoin d'aide SVP
    Par ramime dans le forum Langage SQL
    Réponses: 12
    Dernier message: 25/03/2009, 16h30
  2. headers already sent by ..encore une fois !
    Par marveljojo75 dans le forum Langage
    Réponses: 2
    Dernier message: 05/09/2008, 19h02
  3. Questionnement File of encore une fois ;)
    Par the_clansman dans le forum Delphi
    Réponses: 4
    Dernier message: 09/03/2007, 23h27
  4. Hebergement + GD (encore une fois)
    Par legillou dans le forum Langage
    Réponses: 6
    Dernier message: 28/07/2006, 13h19

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