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.  [ 1 post ] 
Author Message
 Post subject: Illegal attempt to associate a collection with two open sess
PostPosted: Tue Feb 17, 2009 4:39 am 
Beginner
Beginner

Joined: Fri Sep 26, 2008 9:19 am
Posts: 20
Location: Belgium
Hibernate version: 2.0

Hey guys,
I've just created a Two way relational mapping between two objects (one to many with bag (IList<Child>) and many-to-one object in other mapping)
Now i'm getting the error :
Illegal attempt to associate a collection with two open sess

before i've added the IList in my object (and mapping), i did not get this error.

Here's my code

ERROR OCCURS ON object obj = base.PerformSaveOrUpdate(evt); (in Custom SaveEventListener)

Mapping

Parent:
Code:
    <bag name="LookupOutputs" inverse="true" cascade="all-delete-orphan" lazy="false">
      <key column="KbaID" />
      <one-to-many class="ET.Deap.Common.Model.LookupOutput" not-found="exception"/>
    </bag>


Child:
Code:
    <many-to-one name="KbaExtended"
                 cascade="none"
                 column="KbaId"
                 class="ET.Deap.Common.Model.KbaExtended"
                 lazy="false"
                 not-found="exception"
                 not-null="true" />



Code between sessionFactory.openSession() and session.close():
Code:
ITransaction tx2 = session2.BeginTransaction();
try
            {
                // when calling the saveOrUpdate method of the session,
                // NHibernate starts doing his work.
                // through NHibernate we have connected eventlisteners that check every object before the action occurs.
                // check NHibernateEventListeners
                Log.Info("    Starting Save Or Update in the NHibernate Session");

                session2.SaveOrUpdate(ent); // update object in database of the specified project through sessionfactory

                tx2.Commit();
               
            }


Custom SaveOrUpdate EventListener : ERROR OCCURS ON object obj = base.PerformSaveOrUpdate(evt);

Code:
  /// <summary>
        /// When performing ANY save or an update of an entity, this will first be executed
        /// </summary>
        /// <param name="evt"></param>
        /// <returns></returns>
        protected override object [b]PerformSaveOrUpdate(NHibernate.Event.SaveOrUpdateEvent evt)[/b]
        {
            Log.EnterMethod();
            Log.Info(" -- objectType: " + evt.Entity.GetType().FullName);
            Log.Info(" -- object: " + evt.Entity.ToString());

            IDatabaseEntity ent = evt.Entity as IDatabaseEntity;
            ent.FormatValuesForSave();

            if (ent is DataObject)
            {
                Log.Info(" - Entity is a DataObject (basetype). Process DataObject starting now");
                ProcessDataObjectBeforeSaveOrUpdate(ent as DataObject, evt.Session, evt.Entry == null);
            }

            Log.Info(" - Save the object through NHibernate in database (session is in event)");
            object obj =  base.PerformSaveOrUpdate(evt);

            if (obj is DataObject)
            {
                Log.Info(" - Entity is a DataObject (basetype). format the object for use");
                DataObject dataObject = obj as DataObject;
                dataObject.FormatValuesForUse();
                dataObject.LoadFromDatabaseComplete = true;
            }

            Log.LeaveMethod();
            return obj;
        }

        /// <summary>
        /// Do DataObject related things
        /// </summary>
        /// <param name="dataObject">dataobject that is going to be saved</param>
        /// <param name="session">the current opened session</param>
        /// <param name="useChangeLog">if the changelog has to be saved or not</param>
      [b]  private void ProcessDataObjectBeforeSaveOrUpdate(DataObject dataObject, ISession session, bool useChangeLog)[/b]
        {
            Log.EnterMethod();
            Log.Info(" -- useChangelog: " + useChangeLog.ToString());
            Log.Info(" -- " + dataObject.GetType().Name + " object: " + dataObject.ToString());


            Log.Info(" - fill in user and date of save");
            dataObject.LoadFromDatabaseComplete = false;
            dataObject.ModifiedOn = DateTime.Now;
            dataObject.ModifiedBy = "user"; // get out of userUtils

            // check if the object is a new object or this is an update of an existing object
            // if there is an id --> update, new object will return null
            object id = ReturnIdOrNull(dataObject);

            if (useChangeLog && id != null) // if there is an Id --> update so changelog (new object = null)
            {
                Log.Info(" - start to create a changelog to save to the database");
               
                ValidationResult vr = new ValidationResult(false);
                Log.Info(" - get object like it exists in the database before this save");
                DataObject previousObject = (DataObject)session.Get(dataObject.GetType(), id);

                // fill the changelog
                ChangeLog chg = new ChangeLog();
                chg.Blob = previousObject.ToBlob();
                chg.DatabaseAction = DatabaseAction.Update;
                chg.ModifiedBy = dataObject.ModifiedBy;
                chg.ModifiedOn = dataObject.ModifiedOn;
                chg.ObjectId = id.ToString();//dataObject.GetType().InvokeMember("Id", System.Reflection.BindingFlags.GetProperty, null, dataObject, null).ToString();
                chg.ObjectType = (DatabaseObjectType)Enum.Parse(typeof(DatabaseObjectType), dataObject.GetType().Name.ToString());
                chg.ObjectVersion = dataObject.Version;
                chg.NameValuePairs = dataObject.NameValuePairs;

                // get previousObject out of session. Two objects with the same type and id will cause problems
                session.Evict(previousObject);

                try
                {
                    // save it
                    session.Save(chg);
                }
                catch
                {
                    // handle exception in upper level. there we can give information back to the user
                    throw;
                }
   
            }
            else
            {
                dataObject.CreatedBy = "user"; // get out of userUtils
                dataObject.CreatedOn = dataObject.ModifiedOn;
            }
            Log.LeaveMethod();
        }


Full stack trace of any exception that occurs:

at NHibernate.Collection.AbstractPersistentCollection.SetCurrentSession(ISessionImplementor session)
at NHibernate.Event.Default.OnUpdateVisitor.ProcessCollection(Object collection, CollectionType type)
at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Object value, IType type)
at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Int32 i, Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractVisitor.ProcessEntityPropertyValues(Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractVisitor.Process(Object obj, IEntityPersister persister)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformUpdate(SaveOrUpdateEvent event, Object entity, IEntityPersister persister)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsDetached(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at ET.Deap.DataAccessLayer.NHibernateEventListeners.CustomSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent evt) in C:\data\Projects\ET3_DEAP_TEST\ET.Deap\Data Layer\ET.Deap.DataAccessLayer\NHibernateEventListeners\CustomSaveEventListener.cs:line 46
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
at ET.Deap.DataAccessLayer.Repositories.Repository`2.Save(TEntity ent, Int16 projectId, ValidationResult& vr) in C:\data\Projects\ET3_DEAP_TEST\ET.Deap\Data Layer\ET.Deap.DataAccessLayer\Repositories\Repository.cs:line 178


Name and version of the database you are using:

SQL Server 2005

The generated SQL (show_sql=true):


Debug level Hibernate log excerpt:




Read this: http://hibernate.org/42.html
Code:
Code:


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

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.