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 :

Hibernate : Lazy / eager : failed to lazily initialize a collection of role:


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut Hibernate : Lazy / eager : failed to lazily initialize a collection of role:
    Bonjour.

    J'ai un probleme simple avec hibernate et struts 2.

    J'ai un objet Tarif qui contient une liste de tarifValeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <class name="cpte.hibernate.CpteTarif" table="CPTE_TARIF">
            ....
            <set name="cpteTarifvaleurs" table="CPTE_TARIFVALEUR" inverse="true" lazy="true" cascade="all" fetch="select">
                <key>
                    <column name="TAR_ID" precision="22" scale="0" not-null="true" />
                </key>
                <one-to-many class="cpte.hibernate.CpteTarifvaleur" />
            </set>
        </class>
    Sur la page jsp qui affiche la liste des tarifs, je peux cliquer sur un lien qui affiche le détail de celui-ci (dont ces valeurs).

    Dans struts, je fais donc :
    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
     
    	public String loadTarif() throws Exception
        {
    		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
    		long tarifId = Long.parseLong(request.getParameter("tarif.tarId"));
    		tarif = CpteTarifDao.getInstance().get(tarifId); 
    		if(tarif==null)
    		{
    			addActionError(getText("error.baseDeDonnees"));
    			return INPUT;
    		}
     
    		HibernateUtil.closeSession();
    		return SUCCESS;
        }
    puis dans la jsp qui suis, j'ai le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <c:forEach var="tarifValeur"
    					items="${tarif.cpteTarifvaleurs}"
    					varStatus="status">
    					<tr>
    						<td>${tarifValeur.valId}</td>
    						<td><fmt:formatDate  pattern="dd/MM/yyyy"  value="${tarifValeur.valDateEffet}"/></td>
    						<td><fmt:formatDate  pattern="dd/MM/yyyy"  value="${tarifValeur.valDateFin}"/></td>
    						<td><fmt:formatNumber value="${tarifValeur.valMontant}" type="currency" currencySymbol="&euro;"/></td>
    					</tr>
     
    				</c:forEach>
    Ce code affiche l'erreur : org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: cpte.hibernate.CpteTarif.cpteTarifvaleurs, could not initialize proxy - no Session
    car la session est close (je la ferme dans loadTarif()).
    Bien sur, si je ne ferme pas la session préalablement, ca fonctionne correctement, mais j'avais vu que ne pas fermer une session pouvait poser des problèmes lors d'update dans un précédent message sur le forum.

    Doit-on mettre dans chaque jsp une ouverture de session hibernate en début et une fermeture en fin? je ne pense pas que c'est la solution non plus...
    Je ne souhaite pas utiliser le mode "eager". Le chargement à la demande m'a l'air mieux car ca ne va pas tout charger dès le début.

    OButterlin : dans un précédent message vous disiez :
    Dans mon exemple, effectivement, il n'y a pas l'ouverture/fermeture de la session parce que c'est géré au niveau d'un filtre.
    La session est ouverte en début de request et fermée en fin de response.
    .
    Comment faire cela sachant qu'il y a deja un filtre sur mon application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
     
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    Merci d'avance

    Quelqu'un sait

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Je ne connais pas struts2 mais j'étendrais la classe en redéfinissant la méthode doFilter(...)
    Quelque chose comme ceci
    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
    ...
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
        {
            try
            {
                // on ouvre éventuellement la session ici
    
                chain.doFilter(request, response);
            }
            catch (Throwable t)
            {
                System.out.println("doFilter error : " + t.toString());
            }
            finally
            {
                // on ferme la session ici
            }
        }
    ...
    Mais bon, comme dit, je ne connais pas struts2 et je ne sais pas ce que fait ce filtre, donc, c'est sans garantie
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut
    J'ai lu qu'on pouvais avoir deux filtres déclarés dans le sens des <filter-mapping>.

    Donc quand vous dites :
    j'étendrais la classe
    , il suffit que je crée un deuxième filtre (placé en premier) avec le code donné qui ne fait qu'ouvrir et fermer la connexion hiberate.

    A suivre...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Le plus propre est d'avoir effectivement un deuxième filtre qui ouvre et ferme la session hibernate. Et tu mappe ce filtre sur les requête qui utilisent hibernate. Donc a priori sur struts


    Par contre, etendre le filtre Struts => beurk, ça n'a aucun intérêt selon moi.

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Le plus propre est d'avoir effectivement un deuxième filtre qui ouvre et ferme la session hibernate. Et tu mappe ce filtre sur les requête qui utilisent hibernate. Donc a priori sur struts

    Par contre, etendre le filtre Struts => beurk, ça n'a aucun intérêt selon moi.
    Je n'utilise pas struts2 donc je ne sais pas trop ce qu'est sensé faire le filtre mais en struts1, j'étendais le préprocesseur de struts, c'était bien plus intéressant qu'un simple filtre.

    Ceci dit, oui, on tu peux créer un autre filtre et le placer devant, pas de soucis...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut
    Cela fonctionne en gérant un second filtre.

    Par contre, j'ai une question sur (pas sur la même erreur), mais qui concerne le meme objet (Tarif et TarifValeur).

    Je n'avais pas de problème avant l'utilisation d'Hibernate. Il doit donc y avoir une subtilité.
    Avec Hibernate, le tarifvaleurs est un set, alors qu'avant, avec mes dao manuelles, je faisais un arrayList.

    La page de modification est la suivante : formulaire sur le tarif modifiable et formulaire sur la liste des valeurs (non modifiable) mais qui s'affiche en dessous pour que la liste des valeurs du tarifs soit transmise lors du sumit :
    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
     
    			<s:form name="tarifForm" action="">
    				<s:textfield name="tarif.tarId" readonly="true" 
    					label="%{getText('label.tarif.id')}" />
    				<s:textfield name="tarif.tarLibelle" required="true"
    					label="%{getText('label.tarif.libelle')}" />
    				<s:textfield name="tarif.tarNomArticle" required="true"
    					label="%{getText('label.tarif.nomArticle')}" />
    				<s:textfield name="tarif.tarGroupeMarchandise" required="true"
    					label="%{getText('label.tarif.groupeMarchandise')}" />
     
    				<table id="TarifValeur" class="tablesorter">
    			<thead>...</thead>
    			<tbody>
     
    				<s:iterator  value="tarif.cpteTarifvaleurs" var="tarifValeur" status="status"  >
    				<tr>
    					<td><s:textfield theme="simple" cssClass="inputReadOnlyTransparent" readonly="true" name="tarif.cpteTarifvaleurs[%{#status.index}].valId" value="%{valId}"/></td>
    					<td><s:textfield theme="simple" cssClass="inputReadOnlyTransparent" readonly="true" name="tarif.cpteTarifvaleurs[%{#status.index}].valDateEffet" value="%{valDateEffet}"/></td>
    					<td><s:textfield theme="simple" cssClass="inputReadOnlyTransparent" readonly="true" name="tarif.cpteTarifvaleurs[%{#status.index}].valDateFin" value="%{valDateFin}"/></td>
    					<td><s:textfield theme="simple" cssClass="inputReadOnlyTransparent" readonly="true" name="tarif.cpteTarifvaleurs[%{#status.index}].valMontant" value="%{valMontant}"/></td>
    					<td>
    				</tr>
    				</s:iterator>
    Les valeurs du tarifs s'affichent correctement, mais à la validation du formulaire, j'ai des erreurs sur tous les champs du tableau :
    2014-03-07 09:45:56,577 WARN com.opensymphony.xwork2.ognl.OgnlValueStack - Error setting expression 'tarif.cpteTarifvaleurs[0].valId' with value '[Ljava.lang.String;@65919c1f'
    ognl.NoSuchPropertyException: java.util.HashSet.0

    Cela se comprends car l'id est un long, les dates sont des dates et le montant est un bigDecimal donc pas des String.

    Pour votre information, je suis obligé de mettre la liste dans un textField car si je fais un tableau basique, les champs sont perdu si la validation du formulaire ci-dessus (via les fichier_validation.xml) retourne un fieldError.

    Cdt.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 18/01/2015, 19h05
  2. Failed to lazily initialize a collection
    Par Grumium dans le forum Hibernate
    Réponses: 8
    Dernier message: 27/10/2009, 16h35
  3. Réponses: 5
    Dernier message: 23/10/2009, 14h02
  4. failed to lazily initialize a collection of role ?
    Par zuzuu dans le forum Hibernate
    Réponses: 3
    Dernier message: 25/02/2009, 16h02
  5. Réponses: 1
    Dernier message: 04/04/2007, 09h17

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