-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Illegal attempt to associate a collection
PostPosted: Thu Jan 22, 2004 11:00 pm 
Beginner
Beginner

Joined: Tue Jan 06, 2004 4:51 pm
Posts: 48
Hi,

I understand that this exception is quite self-explanatory:

Code:
net.sf.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions


However, I can't identify where in my code it could possibly be. I am using the struts plug-in. I have a form, an action to initialize the form, and the action that is performed when the form is submitted. It is in the submission action, when I try to update one of my collections, that I get this error (and strangely, not the other collection which is initialized in much the same way). I have several object managers that contain a session object. The constructor of these managers grab a session from the sessionFactory. In the finalize method, these managers close the session, so that they do not persist over one request.


Please tell me where the two open sessions/collections are! I will try to include everything but let me know if you need more information.

Here is the structure Study contains a Collection of Versions that has a collection of versionStatuses. As you will see in the log output, versionStatus updates just fine:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
  <!-- table created by: CREATE TABLE KEYWORDS ( ID IDENTITY, NAME VARCHAR(25) ); -->
  <class name="com.cc.tss.Study" table="study">
       
    <id name="id" type="integer" column="id">
        <generator class="sequence">
            <param name="sequence">study_id_seq</param>
        </generator>
    </id>
       
    <property name="number" column="num" type="int" not-null="true"/>
    <property name="description" column="name" type="string"/>
    <property name="inUse" column="in_use" type="boolean"/>
    <property name="dueDate" column="due_date" type="date"/>
   
    <set
        name="versions"
        inverse="true"
        lazy="true"
        order-by="name asc">
       
        <key column="study_id"/>
        <one-to-many class="com.cc.tss.Version"/>
    </set>
   
    <many-to-one
        name="studyType"
        class="com.cc.tss.StudyType"
        column="type"/>
       
    <many-to-one
        name="allocation"
        class="com.cc.tss.Allocation"
        column="allocation_id"/>
       
  </class>
</hibernate-mapping>


Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
          "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
  <!-- table created by: CREATE TABLE KEYWORDS ( ID IDENTITY, NAME VARCHAR(25) ); -->
  <class name="com.cc.tss.Version" table="version">
       
    <id name="id" type="integer" column="id">
        <generator class="sequence">
            <param name="sequence">version_id_seq</param>
        </generator>
    </id>
       
    <property name="name" column="name" type="string" not-null="true"/>
    <property name="numberOfCompletionsRequired" column="comp_req" type="int"/>
    <property name="estimatedTiming" column="est_timing" type="float"/>
    <property name="inUse" column="in_use" type="boolean"/>
   
    <set
        name="versionStatusCode"
        inverse="true"
        lazy="true">
       
        <key column="version_id"/>
        <one-to-many class="com.cc.tss.VersionStatus"/>
    </set>
   
    <many-to-one
        name="study"
        class="com.cc.tss.Study"
        column="study_id"/>
               
  </class>
</hibernate-mapping>


Here is my Initialize form action:
Code:
public final class ManageStudyFormInit extends Action {
   
    static Logger log = Logger.getLogger(ManageStudyFormInit.class);
   
   public ActionForward execute(ActionMapping mapping,
    ActionForm form, HttpServletRequest request, HttpServletResponse response)
    throws Exception {
       
        log.debug("initializing managestudy form");
        HttpSession session = request.getSession();
       
        if (form == null) {
            form = (ActionForm) session.getAttribute(mapping.getAttribute());
           
            if (form == null) {
                log.debug("creating new form named " + mapping.getAttribute() +" in " + mapping.getScope());
                form = new ManageStudyForm();
                if ("request".equals(mapping.getScope()))
                    request.setAttribute(mapping.getAttribute(), form);
                else
                    session.setAttribute(mapping.getAttribute(), form);
            }
        }
       
        ManageStudyForm msf = (ManageStudyForm) form;       
        StudyManager sm = null;
        Study study = null;   
       
        try {
            sm = new StudyManager();
       
            Integer id = null;
                       
            String queryString = request.getQueryString();
            if (queryString != null) {
                Properties p = Util.parseQueryString(queryString);
                id = Integer.valueOf(p.getProperty("id"));
            }           
           
            if (id == null) {
                id = (Integer) request.getAttribute("id");
            }
                       
            if (id != null) {
                study = sm.getStudy(id);
            } else {
                log.debug("Making new study");
                study = new Study();
            }
        } catch (Exception e) {
            log.debug("Error initializing timesheetform", e);
        }
       
        msf.setStudy(study);
               
        log.debug("got study");
                                     
        try {
            setOptions(msf, study);
        } catch (Exception e) {
            log.debug("Error setting options", e);
        }                       
       
        log.debug("Setting transactional control token");
        saveToken(request);
        log.debug("Done init");
        sm = null;
        return (mapping.findForward("success"));
    }
   
    private void setOptions(ManageStudyForm msf, Study study) throws Exception {
        log.debug("setOptions()");           
     
        Collection versions = study.getVersions();
        ArrayList vers = new ArrayList(versions);
        msf.setVersions(vers);
       
        ArrayList selectVersions = new ArrayList();
        ArrayList versionStatuses = new ArrayList();
       
        if (versions != null) {                   
            Iterator it = versions.iterator();
           
            while (it.hasNext()) {
                Version v = (Version) it.next();
                log.debug("Version " + v.getId());
                selectVersions.add(new SelectItem(v.getId(), v.getName(), v.getName()));
                versionStatuses.addAll(v.getVersionStatusCode());           
            }
        }
       
        msf.setSelectVersions(selectVersions);
        msf.setVersionStatuses(versionStatuses);
       
        AllocationManager am = new AllocationManager();
        StudyTypeManager stm = new StudyTypeManager();       
       
        ArrayList allocations = am.getAllocations();
        ArrayList studyTypes = stm.getStudyTypes();
       
        ArrayList selectStudyTypes = new ArrayList();
        ArrayList selectAllocations = new ArrayList();
       
        if (studyTypes != null) {
            Iterator it = studyTypes.iterator();
           
            while (it.hasNext()) {
                StudyType v = (StudyType) it.next();
                selectStudyTypes.add(new SelectItem(v.getId(), v.getDescription(), v.getDescription()));               
            }
        }               
       
        selectAllocations.add(new SelectItem(new Integer(0), "", ""));               
        if (allocations != null) {
            Iterator it = allocations.iterator();
           
            while (it.hasNext()) {
                Allocation v = (Allocation) it.next();
                selectAllocations.add(new SelectItem(v.getId(), v.getDescription(), v.getDescription()));               
            }
        }               
       
        msf.setStudyTypes(selectStudyTypes);
        msf.setAllocations(selectAllocations);

        PayTypeManager patm = new PayTypeManager();
        PieceTypeManager pitm = new PieceTypeManager();       
       
        ArrayList payTypes = patm.getPayTypes();
        ArrayList pieceTypes = pitm.getPieceTypes();
       
        ArrayList selectPieceTypes = new ArrayList();
        ArrayList selectPayTypes = new ArrayList();       
       
        if (payTypes != null) {
            Iterator it = payTypes.iterator();
           
            while (it.hasNext()) {
                PayType v = (PayType) it.next();
                selectPayTypes.add(new SelectItem(v.getId(), v.getType(), v.getType()));               
            }
        }
       
        if (pieceTypes != null) {
            Iterator it = pieceTypes.iterator();
           
            while (it.hasNext()) {
                PieceType v = (PieceType) it.next();
                selectPieceTypes.add(new SelectItem(v.getId(), v.getName(), v.getName()));               
            }
        }               
       
        msf.setPayTypes(selectPayTypes);
        msf.setPieceTypes(selectPieceTypes);
       
        log.debug("done setOptions");
    }     
}


Here is the post-submission action:
Code:
public final class ManageStudyAction extends Action {

    static Logger log = Logger.getLogger(ManageStudyAction.class);
   
    public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) {
        try {
        log.debug("entryAction execute()");
        ActionErrors errors = null;
               
        StudyManager sm = null;       
        ManageStudyForm f = (ManageStudyForm) form;
        Study study = f.getStudy();
        VersionStatusCodeManager vscm = null;       
        study.setVersions(f.getVersions());
        ArrayList vses = f.getVersionStatuses();
        f = null;
        HttpSession session = request.getSession();
        session.setAttribute(mapping.getName(), f);       
        try {
            sm = new StudyManager();       
        } catch (Exception e) {
            log.debug("Error initializing managers", e);
        }
       
        try {
            sm.editStudy(study);
            sm = null;
            vscm = new VersionStatusCodeManager();
            if (!vses.isEmpty()) {
                vscm.editVersionStatus(vses);
            }
        } catch (Exception e) {
            log.debug("Error calculating time", e);
        }
       
        log.debug("ManageStudyAction complete");
        log.debug("going to " + mapping.findForward("success"));
        } catch (Exception e) {
            log.debug("Error", e);
        }
        return (mapping.findForward("success"));
    }
}


Here is the editStudy function from StudyManager:
Code:
       Collection versions = study.getVersions();
       
        try {
            session.saveOrUpdate(study);
            Iterator it = versions.iterator();
           
            while (it.hasNext()) {
                Version v = (Version) it.next();
               
                if (v == null) continue;
               
                log.debug("saveOrUpdate version " + v.getId());
                session.saveOrUpdate(v);                             
            }
            log.debug("flushing");
            session.flush();
        } catch (JDBCException et) {
            SQLException ext = et.getSQLException();
            while (ext != null) {
                log.debug("next", ext);
                ext = ext.getNextException();
            }
        } catch (HibernateException he) {
            log.debug("Error in updating study: ", he);
        } catch (Exception e) {
            log.debug("Error in updating study: ", e);
        }
       
        log.debug("done update");
        return 0;


Here is my log output:
Code:
2004-01-22 22:42:45,436 -- DEBUG com.cc.tss.ManageStudyForm -- ManageStudyform validate()
2004-01-22 22:42:45,437 -- DEBUG com.cc.tss.ManageStudyForm -- validate done
2004-01-22 22:42:45,441 -- DEBUG com.cc.tss.ManageStudyAction -- entryAction execute()
2004-01-22 22:42:45,470 -- DEBUG com.cc.tss.StudyManager -- saveOrUpdate version 2
2004-01-22 22:42:45,477 -- DEBUG com.cc.tss.StudyManager -- Error in updating study:
net.sf.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
...

2004-01-22 22:42:45,497 -- DEBUG com.cc.tss.StudyManager -- done update
2004-01-22 22:42:45,511 -- DEBUG com.cc.tss.VersionStatusCodeManager -- editVersionStatus
2004-01-22 22:42:45,512 -- DEBUG com.cc.tss.VersionStatusCodeManager -- updating 1
2004-01-22 22:42:45,512 -- DEBUG com.cc.tss.VersionStatusCodeManager -- flushing
2004-01-22 22:42:45,576 -- DEBUG com.cc.tss.VersionStatusCodeManager -- done flushing
2004-01-22 22:42:45,576 -- DEBUG com.cc.tss.ManageStudyAction -- ManageStudyAction complete


Top
 Profile  
 
 Post subject: Re: Illegal attempt to associate a collection
PostPosted: Fri Jan 23, 2004 12:57 am 
Newbie

Joined: Thu Sep 18, 2003 1:50 am
Posts: 17
I think these lines(BOLD) are the culprits,

try {
session.saveOrUpdate(study);
Iterator it = versions.iterator();

while (it.hasNext()) {
Version v = (Version) it.next();

if (v == null) continue;

log.debug("saveOrUpdate version " + v.getId());
session.saveOrUpdate(v);
}
log.debug("flushing");
session.flush();
} catch (JDBCException et) {
SQLException ext = et.getSQLException();
while (ext != null) {
log.debug("next", ext);
ext = ext.getNextException();
}
} catch (HibernateException he) {
log.debug("Error in updating study: ", he);
} catch (Exception e) {
log.debug("Error in updating study: ", e);
}

Because you're actually updating study.

_________________
- Jeevan (G1)


Top
 Profile  
 
 Post subject: another error
PostPosted: Fri Jan 23, 2004 10:11 am 
Beginner
Beginner

Joined: Tue Jan 06, 2004 4:51 pm
Posts: 48
Hi,

I think you are suggesting that I flush after I update the study? or close the session altogether?

I added a session.flush() after the saveOrUpdate(study) line and I get the following error:

java.lang.ClassCastException
at net.sf.hibernate.type.SetType.wrap(SetType.java:27)

If I do a session.close() session = sf.openSession() then there are no exceptions thrown but my changes do not save.

ideas?


Top
 Profile  
 
 Post subject: Sometimes
PostPosted: Fri Jan 23, 2004 10:37 am 
Beginner
Beginner

Joined: Tue Jan 06, 2004 4:51 pm
Posts: 48
Hi,

actually, it's still sometimes happening when I use session.close()/init()

On the occasions that the Illegal Attempt exception is not thrown, though, Version updates fine, Version Status seems to update fine no matter what, but nothing in Study will update.

Maybe it's still encountering the ClassCastException but not throwing it?

Thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.