nHibernate Error Illegal attempt to associate a collection with two open sessions

1k Views Asked by At

Prior to the beginning of this December our current code functioned without issue. Recently we have had multiple instances where this error has cropped up. I am having trouble with finding anything wrong with our current code. We are creating one SessionFactory in the global.asax. Then Binding and unBinding for transactions. Here is the code:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        try
        {
            if (!CurrentSessionContext.HasBind(sessionFactory))
            {
                CurrentSessionContext.Bind(sessionFactory.OpenSession());
            }
        }
        catch (Exception ex)
        {
            Logging.logError(ex);
        }
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        try
        {
            var session = CurrentSessionContext.Unbind(sessionFactory);
            if (session != null)
            {
                session.Dispose();
            }
        }
        catch (Exception ex)
        {
            Logging.logError(ex);
        }
    }

Very occasionally when our code runs a session.Update(entity) we get the illegal operation error. Is there anything else that we can do to prevent this issue?

Just in the off chance that it is from the setup of our session factory, here is our code for creating the session factory:

sessionFactory = Fluently.Configure()
                        .Database(OracleClientConfiguration.Oracle10.ConnectionString(System.Configuration.ConfigurationManager.ConnectionStrings["nHibernateConnection"].ToString()).ShowSql())
                        .ExposeConfiguration(cfg => cfg.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, "web"))
                        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyObjectMap>())
                        .ExposeConfiguration(cfg =>
                        {
                            UpdateEventListener updateListener = new UpdateEventListener();
                            cfg.EventListeners.PreUpdateEventListeners =
                                new IPreUpdateEventListener[] { updateListener };
                            cfg.EventListeners.PostLoadEventListeners =
                                new IPostLoadEventListener[] { updateListener };
                            cfg.EventListeners.PostUpdateEventListeners =
                                new IPostUpdateEventListener[] { updateListener };
                            cfg.EventListeners.PreInsertEventListeners =
                                new IPreInsertEventListener[] { updateListener };
                            cfg.EventListeners.PostInsertEventListeners =
                                new IPostInsertEventListener[] { updateListener };
                        })
                        .BuildSessionFactory();
1

There are 1 best solutions below

0
On

Could this be something to do with requests running concurrently? I.e. Request 1 starts and sets the contextual session and saves something to the session; Request 2 now starts and sets the contextual session, overwriting the session set by R1; R1 continues, and tries to do somehting with a collection that's associated with the session created by R1.

If this is the case, or something like it, you might need to re-think the use of contextual sessions. It might be better to use DI and inject a session using request scope.