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 :

Pb de session hibernate et recuperation de données (lazy = true)


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 75
    Points : 53
    Points
    53
    Par défaut Pb de session hibernate et recuperation de données (lazy = true)
    Bonjour a tous,

    Je developpe une application web J2EE avec Struts et Hibernate.

    Je rencontre un probleme pour passer des POJO d'une classe a l'autre.

    J'ai une classe Action struts (GetUserListAction) chargée de recuperer une collection d'objets utilisateurs (POJOUser) dans la DB avec hibernate.
    Cette collection est ensuite stockée dans un hashset que je passe a une clsee metier chargée de generer du XML (UserListXML) a partir de ce que contient ce hashet.

    Seulement voila, lorsque je veut lire le hashet dans la classe metier j'obtiens un LazyInitializationException de la part de Hibernate. En parcourant les différents sujets de ce forum et la documentation j'ai compris qu'il sagissait d'un probleme de session hibernate et que plusieures options se présentaient a moi :

    1)- mettre lazy = "false" dans le mapping hibernate pour mon POJOUser (j'ai fait le test et ca fonctionne tres bien)
    2)- faire l'appel a hibernate dans la classe UserListXML auquel cas plus probleme de session fermée
    3)- d'autre options que je n'ai pas tres bien compris comme "réattacher ton objet à une session et travailler avec ton objet attaché"

    J'écarte dores et déja les 2 premieres options car la solution 1) va me poser des problèmes de performance a moyen terme (montée en charge de l'application) et solution 2) car j'aimerai que cette classe de génération XML reste aussi independante que possible pour pouvoir la réutiliser dans d'autres cas de figure.

    Donc j'aimerai pouvoir faire cet recuperation d'objets avec Hibernate dans mon Action struts et la passer a la classe UserListXML.

    Si qqn pouvait m'expliquer quleques aproches mentionnées dans l'option 3) je lui en serait tres reconaissant !

    voici un peu de source pour vous faire une idée

    GetUserListAction
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    public ActionForward execute(
    		ActionMapping mapping,
    		ActionForm form,
    		HttpServletRequest request,
    		HttpServletResponse response) 
    		throws
    		Exception, //the exceptions generated by the other classes used here such as tokenclient
    		IOException,
    		ServletException 
    		{
     
    		 HttpSession session = request.getSession(); 
    		 GetUserListForm f = (GetUserListForm) form;
    		 String searchString = f.getSearchString();
    		 String searchType = f.getSearchType();
    		 Set userList = new HashSet();
     
     
    		 //if mode is login
    		 if (searchType.equals("login")){
    			POJOUser user = new POJOUser();
     
    			Session hibSession;
    			Transaction tx;
    			hibSession = HibernateUtil.currentSession();
    			tx = hibSession.beginTransaction();
     
    			Query query = hibSession.createQuery("from POJOUser u where u.login = '" + searchString + "'");
     
    			for (Iterator it = query.iterate(); it.hasNext();) {
    				userList.add((POJOUser) it.next());
    			}		
    			--------> NORMALEMENT A CET ENDROIT MON HASHET DEVRAIT ETRE REMPLI (C'est le cas avec lazy = false) <---------
     
     
    			tx.commit();
    			HibernateUtil.closeSession();
    		 }
     
     
    //		cook the xml   						
    		 UserListXML uxml = new UserListXML(userList);  
    		 StringBuffer strXML;
     
    		 strXML = uxml.cookXML();
     
    ...



    UserListXML
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    public class UserListXML {
     
    	Set userList;
     
    //	 constructor
    	public UserListXML(Set userList){
    		this.userList = userList;
    	}
     
    	public StringBuffer cookXML(){
    		StringBuffer strXML = new StringBuffer();
     
    //		build header
    		strXML.append("<?xml version=\"1.0\" ?>");
    		strXML.append("<userslist>");
    		strXML.append("<users q='"+Integer.toString(userList.size())+"'>");
     
    		-----> CA PLANTE PAR ICI <-------
    		Iterator iter = userList.iterator();
    		while(iter.hasNext()){	
    			strXML.append("<user>");
    				POJOUser user = (POJOUser) iter.next();
     
    				strXML.append("<login>");
    					strXML.append(user.getLogin().toString());
    				strXML.append("</login>");
     
    				strXML.append("<firstname>");
    					strXML.append(user.getFirstName().toString());
    				strXML.append("</firstname>");
     
    				strXML.append("<lastname>");
    				strXML.append(user.getLastName().toString());
    				strXML.append("</lastname>");
    				strXML.append("<custid>");
    					strXML.append("todo");
    				strXML.append("</custid>");
     
    				strXML.append("<contractid>");
    					strXML.append(user.getContractId().toString());
    				strXML.append("</contractid>");
     
    				strXML.append("<accttype>");
    					strXML.append("todo");
    				strXML.append("</accttype>");
     
    				strXML.append("<status>"); //activationstatus in DB
    					strXML.append(user.getActivationStatus().toString());
    				strXML.append("</status>");
     
    			strXML.append("</user>");
    		}
    		strXML.append("</users>");
    		strXML.append("</userslist>");
     
        //spit the thing
    	return strXML;
    	}

    voila j'espere que ca suffira pour saisr le probleme.

    Merci de votre aide !
    A+

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 156
    Points : 165
    Points
    165
    Par défaut
    Un moyen simple de résoudre ton problème c'est d'utiliser une session par page. Tu ouvres la session hibernate en début de ton action Struts et tu la referme en fin.

    A partir du moment ou tu appelles ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    tx.commit();
    HibernateUtil.closeSession();
    les objets deviennent détachés et tu ne peux plus charger les associations qui ne l'ont pas été au préalable (soit par lasy="false" soit par un accès à la collection soit par une instruction fetch).
    Donc si tu fait ton appel à ta classe XML avant le closeSession() ça marchera. Si tu n'as qu'une seule classe persistante c'est ce que je te conseillerai.

    Si tu as un modèle de donné plus étoffé, tu peux passer par une couche service et des objets de transfert.

    Dans ta couche service tu ouvre la session hibernate, tu récupère toutes les données dont tu as besoin (donc tu peux faire une méthode qui récupère l'objet sans les collections et une qui le récupère avec les collection), tu copie tout ça dans un JavaBean qui sert d'objet de transfert, tu fermes la session et tu renvoie ton bean.

  3. #3
    Membre habitué
    Inscrit en
    Juillet 2004
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 152
    Points : 173
    Points
    173
    Par défaut
    Dans la cas que tu décris, quel est l'interet de mettre un lazy à true, puisque tu parcours la totalite de tes objets pour generer le XML ?

    Je suis pas persuade qu'il y aura un impact si important en terme de performance

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    75
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 75
    Points : 53
    Points
    53
    Par défaut
    Merci pour vos réponses


    Neuromancien :

    Si tu as un modèle de donné plus étoffé, tu peux passer par une couche service et des objets de transfert.
    Je pense que je vais opter pour cette option car mon application va énormément évoluer.

    Par contre si tu pouvais me pointer vers un exemple de comment integrer ca a mon projet ca me serait tres utile car je ne sais pas vraiment par ou commencer.
    Un tutoril ou de la doc serait le bien venue.


    dude :
    quel est l'interet de mettre un lazy à true
    Justement parceque sans ce lazy = true les objets ne sont pas chargés en memoire lors du passage de mon hashet a la classe génératrice de xml.



    Merci pour votre aide!

  5. #5
    Membre habitué
    Inscrit en
    Juillet 2004
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 152
    Points : 173
    Points
    173
    Par défaut
    Citation Envoyé par azpublic
    Citation Envoyé par dude
    quel est l'interet de mettre un lazy à true
    Justement parceque sans ce lazy = true les objets ne sont pas chargés en memoire lors du passage de mon hashet a la classe génératrice de xml.
    C'est le contraire, non ?...
    sans lazy=true (ie lazy=false), tous les objets seront chargés en mémoire

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 156
    Points : 165
    Points
    165
    Par défaut
    Au niveau des tutos je n'en ai pas, par contre en cherchant un petit peu avec les mots clés "architecture en couches services DAO" sous Google tu as pleins de liens interressants (dont des sujets sur dvp ou ça a déja été traité).

    Les exemples de code sont pour .NET mais le principe reste valable en J2EE. Ils expliquent très bien le principe et ils parlent entre autre de ton problème de sessions. Pour la partie interception dont ils parlent à un moment tu peux jeter un coup d'oeil sur Spring (il y a des tutos Spring sur dvp, c'est avec ça que j'ai débuté). Et pour les DTO qu'ils veulent remiser au placard, je te conseille de les utiliser avant d'avoir l'expérience nécessaire pour juger si ils sont vraiment utiles ou pas (mais c'est vrai qu'ils ne sont plus indispensables, entre autres avec Hibernate).

  7. #7
    zev
    zev est déconnecté
    Membre actif
    Inscrit en
    Octobre 2004
    Messages
    204
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 204
    Points : 220
    Points
    220
    Par défaut
    Attention si vous ne précisez pas le mode lazy:
    dans hibernate2, par defaut, lazy = false (tous le objets sont chargés)
    dans hibernate3, par defaut, lazy = true (les objets ne sont pas chargés)

    dans le doute il faut mieux toujours préciser lazy = false ou true dans les fichiers hbm.

Discussions similaires

  1. Réponses: 18
    Dernier message: 10/11/2006, 13h33
  2. [Hibernate][Spring] Session Hibernate initialisée
    Par mauvais_karma dans le forum Hibernate
    Réponses: 12
    Dernier message: 08/08/2005, 13h07
  3. PB de recuperation de données en asynchrone !!
    Par Stopher dans le forum C++
    Réponses: 8
    Dernier message: 01/02/2005, 23h20
  4. Recuperer des données d'access
    Par Lucier dans le forum MFC
    Réponses: 18
    Dernier message: 25/11/2004, 10h29
  5. Réponses: 3
    Dernier message: 22/02/2004, 20h09

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