-->
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.  [ 3 posts ] 
Author Message
 Post subject: Intermittent errors in deployed app
PostPosted: Mon Nov 14, 2005 4:38 pm 
Regular
Regular

Joined: Tue May 31, 2005 3:18 pm
Posts: 117
Location: Houston
I'm using NHibernate 0.7.00 and ASP.NET in a deployed application.

I have been reluctant to upgrade the version for fear of introducing lots of bugs or changed usage etc... (this may be the answer to my problem, but let me first explain)...

I am getting *very* intermittent errors on the site, today I received 4, which is unusually high. Usually I get about 1 every 2 weeks.

The errors are generally disturbing, but don't necessarily hinder the user much; they just have to refresh the page.

Here are the 3 most common errors I'm getting:
Exception: NHibernate.AssertionFailure
Message: hibernate has a bug processing collections


Exception: NHibernate.HibernateException
Message: found shared references to a collection



Exception: System.InvalidOperationException
Message: ExecuteReader requires an open and available Connection. The connection's current state is Closed.


I have the log statements from each of these errors, but most of them don't look suspicious.

I should also note that I am using the session-per-request pattern with an HttpModule, which switches to a singleton in the absense of HttpContext.

Any ideas? I can post code/mapping files if necessary. Should I just upgrade to the latest NHibernate?

Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 14, 2005 5:39 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Your symptoms in general look like a threading problem. Are you accessing the same ISession from multiple threads? Or maybe the same objects? Can you post your session-management code?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 14, 2005 5:50 pm 
Regular
Regular

Joined: Tue May 31, 2005 3:18 pm
Posts: 117
Location: Houston
I was thinking the same thing.

Here's what I have:

Code:
public class NHManager : IDisposable
   {
      private static object _lockDummy = new object();

      private NHManager()
      {
         //read configuration here
         _config = new Configuration();

         //add the classes in the assembly
         _config.AddAssembly("Foundation");
         
         //construct the global factory
         _factory = _config.BuildSessionFactory();         
      }

      private Configuration _config = null;

      private ISessionFactory _factory = null;
      public ISessionFactory SessionFactory
      {
         get { return _factory;    }
      }

      private static NHManager _instance = null;
      public static NHManager Instance
      {
         get
         {
            //lock for threadsafe operation
            lock(_lockDummy)
            {
               if(_instance == null)
               {
                  _instance = new NHManager();
               }
            }

            return _instance;
         }
      }

I actually JUST now placed that lock on the singelton to secure threadsafety for the factory. This may alleviate some of my concerns.

Here's the HttpModule:
Code:
public class NHSessionModule : IHttpModule, System.Web.SessionState.IReadOnlySessionState
   {
      private ISession _session = null;
      private const string NHSESSION = "NHSESSION";

      public NHSessionModule()
      {
      }

      #region IHttpModule Members

      public void Init(HttpApplication application)
      {
         //hook events
         application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);
         application.PostRequestHandlerExecute += new EventHandler(application_PostRequestHandlerExecute);            
      }

      public void Dispose()
      {
      }

      #endregion      
   
      private void application_PreRequestHandlerExecute(object sender, EventArgs e)
      {
         HttpApplication app = sender as HttpApplication;         

         Logger.Log("NHSessionModule", string.Format("BeginRequest for {0} :  Getting ISession", app.Request.Url.ToString()));
         //check to see if there is a floating session we can use                  
         if( app.Context.Session != null &&
            app.Context.Session[NHSESSION] != null)
         {
            Logger.Log("Floating session found, loading");
            //load it from session instead of creating a new one
            _session = app.Context.Session[NHSESSION] as ISession;
            if(! _session.IsConnected)
            {
               Logger.Log("Session was disconnected.  Reconnecting...");
               _session.Reconnect();
            }
         }
         else
         {
            //check for local session
            if(_session == null)
            {               
               //create new session from our NH Manager class
               Logger.Log("Creating ISession from SessionFactory");
               _session = NHManager.Instance.SessionFactory.OpenSession();
            }
            else
            {
               Logger.Log("NHSessionModule", "Using previous ISession");
               if(! _session.IsConnected)
               {
                  Logger.Log("NHSessionModule", "Reconnecting previous session");
                  _session.Reconnect();
               }         
            }            
         }

         //add to context for future requests
         Logger.Log("Adding current session to Context");
         app.Context.Items.Add(NHSESSION, _session);         
      }

      private void application_PostRequestHandlerExecute(object sender, EventArgs e)
      {
         HttpApplication app = sender as HttpApplication;
         try
         {

            Logger.Log("NHSessionModule", string.Format("End Request for {0}: handling ISession", app.Request.Url.ToString()));
         
            //if session is floating, disconnect it, but leave it floating
            if( app.Context.Session != null &&
               app.Context.Session[NHSESSION] != null)
            {
               Logger.Log("NHSessionModule", "Floating session found, disconnecting and leaving it floating.");
               ((ISession)app.Context.Session[NHSESSION]).Disconnect();
               return;
            }

            //otherwise, get the session from the context         
            _session = app.Context.Items[NHSESSION] as ISession;         

            //flush and disconnect it
            Logger.Log("NHSessionModule", "Flushing, disconnecting, and closing ISession");
            if(_session != null)
            {
               if(_session.IsConnected)
               {
                  Logger.Log("NHSessionModule", "Session was connected, flushing and disconnecting");
                  _session.Flush();
                  _session.Disconnect();
               }
               if(_session.IsOpen)
               {
                  Logger.Log("NHSessionModule", "Session was open, closing");
                  _session.Close();
               }
            }

            Logger.Log("NHSessionModule", "Dereferencing Context item");
            //dereference context
            app.Context.Items[NHSESSION] = null;
         }
         catch(NullReferenceException nullRefExc)
         {
            Logger.LogException("NHSessionModule", "Error trying to end the request:  probably no session object", nullRefExc);
         }
      }
   }


The stuff about "Floating Sessions" up there isn't currently being used... I couldn't get it to work properly.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.