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 :

[erreur] Illegal attempt to associate a collection with two open sessions


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut [erreur] Illegal attempt to associate a collection with two open sessions
    Salut,

    Avec j'obtiens l'erruer suivante avec Hibernate :

    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
    org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
            at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
            at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
            at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
            at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
            at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
            at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
            at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:268)
            at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:217)
            at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
            at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
            at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
            at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
            at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
            at be.qspin.qats.business.HibernateUtility.setRow(HibernateUtility.java:99)
            at be.qspin.qats.business.Applicants.saveKeywords(Applicants.java:152)
            at be.qspin.qats.struts.action.ManageKeywordAction.execute(ManageKeywordAction.java:76)
            at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
            at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
            at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
            at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
            at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
            at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
            at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
            at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
            at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
            at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
            at java.lang.Thread.run(Thread.java:595)
    j'ai compris que 2 sessions s'ouvrent en meme temps
    mais je ne sais pas vraiment comment la résoudre. Pourtnat, a la fin de chaqsue transaction, je faire bien ma session...

    voici mon code :

    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 static void saveKeywords(Applicant appl, String[] key){
            Set s = new HashSet();
            if (!appl.getKeywords().isEmpty())
                s= appl.getKeywords();
            Keyword kw = new Keyword();
            for (int j = 0; j<key.length; j++){
                kw = (Keyword) HibernateUtility.getRow(Keyword.class, "id", new Integer(key[j]));
                if (kw !=null)
                    s.add(kw);
            }
            if (!s.isEmpty()){
                appl.setKeywords(s);
                appl = (Applicant) HibernateUtility.setRow(appl);
            }
        }
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    /*
     * HibernateUtility.java
     *
     * Created on 18 novembre 2006, 13:43
     *
     * To change this template, choose Tools | Template Manager
     * and open the template in the editor.
     */
     
    package be.qspin.qats.business;
     
    import be.qspin.qats.struts.plugin.HibernatePlugIn;
     
    import java.util.List;
    import java.io.Serializable;
    import org.hibernate.Criteria;
    import org.hibernate.Session;
    import org.hibernate.Query;
    import org.hibernate.Transaction;
    import org.hibernate.criterion.Restrictions;
     
    public class HibernateUtility {
     
        /** Creates a new instance of HibernateUtility */
        public HibernateUtility() {
        }
     
        /*
         *provide a hibernate session
         *@return Session
         */
        public static Session getHibernateSession() {
            return HibernatePlugIn.getSessionFactory().openSession();
        }
     
        /*
         *return an record according to id
         *@param Class
         *@param Serializable
         *@return Object
         */
        public static Object getRow(Class aClass, Serializable id) {
            Session session = getHibernateSession();
            Object obj = session.get(aClass, id);
            session.close();
            return obj;
        }
     
        /*
         *return one record accoding to parameters
         *@param Class
         *@param String
         *@param String
         *@return Object
         */
        public static Object getRow(Class aClass, String attributeName, String attributeValue) {
            Session session = getHibernateSession();
            Criteria crit = session.createCriteria(aClass);
            crit.add(Restrictions.eq(attributeName, attributeValue));
            Object obj = crit.uniqueResult();
            session.close();
            return obj;
        }
     
        public static Object getRow(Class aClass, String attributeName, Integer attributeValue) {
            Session session = getHibernateSession();
            Criteria crit = session.createCriteria(aClass);
            crit.add(Restrictions.eq(attributeName, attributeValue));
            Object obj = crit.uniqueResult();
            session.close();
            return obj;
        }
     
        /*
         *return all record
         *@param Class
         *@return List
         */
        public static List getRow(Class aClass){
            Session session = getHibernateSession();
            Criteria crit = session.createCriteria(aClass);
            List result = crit.list();
            session.close();
            return result;
        }
     
     
        /*
         *record an object
         *@param Object
         */
        public static Object setRow(Object obj) {
            Session session = getHibernateSession();
            Transaction tx = session.beginTransaction();
            session.saveOrUpdate(obj);
            tx.commit();
            session.close();
            return obj;
        }
     
        public static List executeRequest(String request){
            System.out.println("Display query : "+request);
            Session session = getHibernateSession();
            Query query = session.createSQLQuery(request);
            return query.list();
        }
    }
    Merci pour l'aide

  2. #2
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut
    personne n'as une idée sur la question?

  3. #3
    BsT
    BsT est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 72
    Par défaut
    En imaginant que la session qui t'a permis d'obtenir Applicant n'est pas fermé, avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            if (!appl.getKeywords().isEmpty())
                s= appl.getKeywords();
    Lorsque tu executes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    appl = (Applicant) HibernateUtility.setRow(appl);
    tu as tes 2 sessions.

    Je pense que tu devrais écrire ton code de la facon suivante (attention je fais des suppositions sur ton mapping ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    openSession();
    ...
    Keyword k;
    tx = session.beginTransaction();
    Applicant a = (Applicant) session.get(Applicant.class, id);
    for(int i = 0; i < key.length; i++) {
         k = (Keyword) session.get(Keyword.class, new Integer(key[i]));
         k.setApplicant(a);
    }
    tx.commit();
    session.refresh(a); // Pour reconstruire le Set Keywords il me semble
    ....
    closeSession();
    Si tu as besoin de la collection Keywords tu peux ajouter une méthode dans Applicant (j'ai écris un générateur de code qui le fait pour moi):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public void addKeywords(Keyword k) {
           if (getKeywords() == null) {
                 setKeywords(new HashSet());
           }
           getKeyWords().add(w);
           k.setApplicant(this);
    }
    et remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     k.setApplicant(a);
     
    par : a.addKeywords(k);
    Mais attention parce que selon le contrat d'utilisation des Set chaque élément est unique, donc Hibernate est obligé de charger complétement le Set pour garantir l'unicité de tes éléments lorsque tu fais getKeywords().add() !

    Stéphane

    Ps : pour rester anonyme retire ton nom du code FG :p

  4. #4
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut
    Je vais essayer comme tu m'as dit, mais je ne comprends pas tous a fait parce que pourtant, à la fin de mes fonctions setRow() et getRow, je ferme pourtant bien la session avec session.close() alors comment ce fait'il quelle soit toujours ouverte?

  5. #5
    Membre éclairé
    Avatar de CPI_en_mousse
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2006
    Messages
    332
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 332
    Par défaut
    j'ai modifie ma fonction 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
    21
    22
    23
    24
    25
    26
     public static void saveKeywords(Applicant appl, String[] key){
            Session session = HibernateUtility.getHibernateSession();
            Transaction tx = session.beginTransaction();
     
            Set s = new HashSet();
            if (!appl.getKeywords().isEmpty())
                s= appl.getKeywords();
            Keyword kw = new Keyword();
     
            //recuperation de l'objet et mise dans le hashset
            for (int j = 0; j<key.length; j++){
                //kw = (Keyword) HibernateUtility.getRow(Keyword.class, "id", new Integer(key[j]));
                Criteria crit = session.createCriteria(Keyword.class);
                crit.add(Restrictions.eq("id", new Integer(key[j])));
                kw = (Keyword) crit.uniqueResult();
                if (kw !=null)
                    s.add(kw);
            }
            if (!s.isEmpty()){
                appl.setKeywords(s);
                //appl = (Applicant) HibernateUtility.setRow(appl);
                session.saveOrUpdate(appl);
            }
            tx.commit();
            session.close();
        }
    mais j'ai toujours la meme erreur.

    en bonus je vous file mes mappings pour Applicant et Keyword

    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     
    <!--
        Document   : Applicant.hbm.xml
        Created on : 25 avril 2007, 10:14
        Author     : f
        Description:
            Mapping fot the applicant entities
    -->
     
     
    <hibernate-mapping default-lazy="false">
        <class name="be.qspin.qats.entities.Applicant" table="APPLICANTS">
            <meta attribute="class-description">
                Define an "Applicant" entity.
            </meta>
            <id name="id" type="integer" column="ID">
                <generator class="increment">
                </generator>            
            </id>
            <property name="lastname" type="string" not-null="true">
                <column name="LASTNAME" length="20" not-null="true"/>
            </property>
            <property name="firstname" type="string" not-null="true">
                <column name="FIRSTNAME" length="20" not-null="true"/>
            </property>
            <property name="gender" type="string" not-null="true">
                <column name="GENDER" length="20" not-null="true"/>
            </property>        
            <property name="birthday" type="timestamp" not-null="false">
                <column name="BIRTHDAY" length="20" not-null="false"/>
            </property>
            <property name="nationality" type="string" not-null="true">
                <column name="NATIONALITY" length="20" not-null="true"/>
            </property>
            <property name="address" type="string" not-null="true">
                <column name="ADDRESS" length="20" not-null="true"/>
            </property>
            <property name="PC" type="string" not-null="true">
                <column name="PC" length="20" not-null="true"/>
            </property>        
            <property name="city" type="string" not-null="true">
                <column name="CITY" length="20" not-null="true"/>
            </property>    
            <property name="country" type="string" not-null="true">
                <column name="COUNTRY" length="20" not-null="true"/>
            </property>  
            <property name="phone" type="string" not-null="true">
                <column name="PHONE" length="20" not-null="true"/>
            </property>    
            <property name="gsm" type="string" not-null="true">
                <column name="GSM" length="20" not-null="true"/>
            </property>  
            <property name="email" type="string" not-null="true">
                <column name="EMAIL" length="50" not-null="true"/>
            </property>   
            <property name="interest" type="string" not-null="true">
                <column name="INTEREST" length="20" not-null="true"/>
            </property>  
            <property name="langCom" type="string" not-null="true">
                <column name="LANG_COM" length="20" not-null="true"/>
            </property>  
            <property name="source" type="string" not-null="true">
                <column name="SOURCE" length="30" not-null="true"/>
            </property>  
            <property name="currentIncome" type="integer" not-null="true">
                <column name="CURRENT_INCOME" length="30" not-null="true"/>
            </property>  
            <property name="desiredIncome" type="integer" not-null="true">
                <column name="DESIRED_INCOME" length="30" not-null="true"/>
            </property>        
            <property name="net" type="string" not-null="true">
                <column name="NET" length="10" not-null="true"/>
            </property>   
            <property name="tempUnit" type="string" not-null="true">
                <column name="TEMP_UNIT" length="10" not-null="true"/>
            </property>           
     
            <many-to-one name="jobTitle" column="JT_ID" class="be.qspin.qats.entities.JobTitle" cascade="none" not-null="true"/>
            <set name="keywords" table="APPLICANTS_KEYWORDS" cascade="none">
                <key column="APPLICANT_ID" not-null="true"/>
                <many-to-many class="be.qspin.qats.entities.Keyword">
                    <column name="KEYWORD_ID" not-null="true"/>
                </many-to-many>                
            </set>  
     
        </class>
    </hibernate-mapping>
    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
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     
    <!--
        Document   : Keyword.hbm.xml
        Created on : 25 avril 2007, 10:14
        Author     : f
        Description:
            Mapping fot the Keyword entities
    -->
     
     
    <hibernate-mapping default-lazy="false">
        <class name="be.qspin.qats.entities.Keyword" table="KEYWORDS">
            <meta attribute="class-description">
                Define an "Keyword" entity.
                @author Florian Guillemotte
                @author fguillemotte@gmail.com
            </meta>
            <id name="id" type="integer" column="ID">
                <generator class="increment">
                </generator>            
            </id>
            <property name="word" type="string" not-null="true">
                <column name="WORD" length="50" not-null="true"/>
            </property>        
     
            <many-to-one name="skill" column="CAT" class="be.qspin.qats.entities.Skill" cascade="none"/>  
     
        </class>
    </hibernate-mapping>

  6. #6
    Membre Expert Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Par défaut
    Je pense qu'il te faudrait ouvrir ta session avant setKeywords() et setRow()
    et la fermer ensuite.

Discussions similaires

  1. Réponses: 13
    Dernier message: 01/03/2011, 17h12
  2. Réponses: 2
    Dernier message: 26/02/2009, 09h07
  3. Réponses: 3
    Dernier message: 28/02/2007, 16h21
  4. Réponses: 2
    Dernier message: 13/10/2006, 17h38
  5. Réponses: 4
    Dernier message: 20/07/2006, 17h26

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