Hi,
I dont know why two sessions are open..
I am unsure which pattern to use for data retrieval with NHibernate - I'm using something I adapted from an open-source project..
I am not expecting you to read all of my code (may take too much time), so if you know of a good pattern to use for an NHibernate helper, then Id be happy to do the tinkering to make it work with my code and get back to you if I still have the same problem.
Thank you so much for your help,
Christian
Here's the code, in case you feel inclined:
Code:
<<<< Databroker Class >>>>
public class DataBroker
{
...
      public NHibernateHelper dataHelper;
...
      public int SaveHotelLocation(HotelLocation hotelLocation)
      {
         ITransaction tx = dataHelper.ActiveSession.BeginTransaction();
         
         try
         {
            hotelLocation.ID = (int) dataHelper.ActiveSession.Save(hotelLocation);
            tx.Commit();
            
         }
         catch (Exception ex)
         {
            if(tx!=null) tx.Rollback();
            throw new Exception("Unable to save hotelLocation", ex);
         }
         finally{   dataHelper.ActiveSession.Close(); }
         return hotelLocation.ID;
      }
...
}
Code:
<<<< NHibernateHelper class >>>>
using System;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using log4net;
using NHibernate;
using NHibernate.Expression;
namespace NHibernateHelper
{
   public class NHibernateHelper
   {
      private static readonly ILog log = LogManager.GetLogger(typeof(NHibernateHelper));
      private ISessionFactory _factory;
      private ISession _activeSession;
      private static IDictionary getConfigurationSection(string configSectionName)
      {
         object config = ConfigurationSettings.GetConfig(configSectionName);
         Hashtable dictionary = new Hashtable();
         if( config == null )
         {
            return null;
         }
         NameValueCollection properties = config as NameValueCollection;
         if( properties == null )
         {
            return null;
         }
         foreach( string key in properties )
         {
            dictionary[ key ] = properties[ key ];
         }
         return dictionary;
      }
      
      /// <summary>
      /// Get the active NHibernate session.
      /// </summary>
      public ISession ActiveSession
      {
         get { return this._activeSession; }
      }
       
      public NHibernateHelper(string configSectionName, Assembly assembly) : this( NHibernateHelper.getConfigurationSection(configSectionName), assembly )
      {
         
      }
       
      public NHibernateHelper(string configSectionName, Assembly assembly, bool openSession) : this( NHibernateHelper.getConfigurationSection(configSectionName), assembly, openSession)
      {
         
      }
      /// <summary>
      /// Create a repository for core objects.
      /// </summary>
       
      public NHibernateHelper(System.Collections.IDictionary properties, Assembly assembly) : this(properties, assembly, false)
      {
      }
      /// <summary>
      /// Create a repository for core objects.
      /// </summary>
      /// <param name="openSession">Indicate if the CoreRepository should open a session and keep it in memory.</param>
      public NHibernateHelper(System.Collections.IDictionary properties, Assembly assembly, bool openSession)
      {
         this._factory = SessionFactory.GetInstance(properties, assembly).GetNHibernateFactory();
         if (openSession)
         {
            this._activeSession = this._factory.OpenSession();
         }
      }
      
      
      /// <summary>
      /// Open a NHibernate session.
      /// </summary>
      public void OpenSession()
      {
         if (this._activeSession == null || ! this._activeSession.IsOpen)
         {
            this._activeSession = this._factory.OpenSession();
         }
         else
         {
            throw new InvalidOperationException("The repository already has an open session");
         }
      }
      /// <summary>
      /// Flushes the current active NHibernate session.
      /// </summary>
      public void FlushSession()
      {
         if (this._activeSession != null && this._activeSession.IsOpen)
         {
            this._activeSession.Flush();
         }
      }
      /// <summary>
      /// Close the active NHibernate session
      /// </summary>
      public void CloseSession()
      {
         if (this._activeSession != null)
         {
            if (this._activeSession.IsOpen)
            {
               this._activeSession.Close();
            }
            this._activeSession.Dispose();
         }
      }
      #region Generic methods
      /// <summary>
      /// Generic method for retrieving single objects by primary key.
      /// </summary>
      /// <param name="type"></param>
      /// <param name="id"></param>
      /// <returns></returns>
      public object GetObjectById(Type type, int id)
      {
         if (this._activeSession != null)
         {
            return this._activeSession.Load(type, id);
         }
         else
         {
            throw new NullReferenceException("The repository doesn't have an active session");
         }
      }
      /// <summary>
      /// Get all objects of a given type.
      /// </summary>
      /// <param name="type"></param>
      /// <returns></returns>
      public IList GetAll(Type type)
      {
         return GetAll(type, null);
      }
      /// <summary>
      /// Get all objects of a given type and add one or more names of properties to sort on.
      /// </summary>
      /// <param name="type"></param>
      /// <param name="sortProperties"></param>
      /// <remarks>Sorting is Ascending order. Construct a specific query/method when the sort order
      /// should be different.</remarks>
      /// <returns></returns>
      public IList GetAll(Type type, params string[] sortProperties)
      {
         ICriteria crit = this._activeSession.CreateCriteria(type);
         if (sortProperties != null)
         {
            foreach (string sortProperty in sortProperties)
            {
               crit.AddOrder(Order.Asc(sortProperty));
            }
         }
         return crit.List();
      }
      /// <summary>
      /// Generic method to insert an object.
      /// </summary>
      /// <param name="obj"></param>
      public void SaveObject(object obj)
      {
         ITransaction trn = this._activeSession.BeginTransaction();
         try
         {
            // Try to find a UpdateTimestamp property and when found, set it to the current date/time.
            PropertyInfo pi = obj.GetType().GetProperty("UpdateTimestamp");
            if (pi != null)
            {
               pi.SetValue(obj, DateTime.Now, null);
            }
            this._activeSession.Save(obj);
            trn.Commit();
         }
         catch (Exception ex)
         {
            trn.Rollback();
            throw ex;
         }
      }
      /// <summary>
      /// Generic method to update an object.
      /// </summary>
      /// <param name="obj"></param>
      public void UpdateObject(object obj)
      {
         ITransaction trn = this._activeSession.BeginTransaction();
         try
         {
            this._activeSession.Update(obj);
            trn.Commit();
         }
         catch (Exception ex)
         {
            trn.Rollback();
            throw ex;
         }
      }
      /// <summary>
      /// Delete a specific object. Settings in the mapping file determine if this cascades
      /// to related objects.
      /// </summary>
      /// <param name="obj"></param>
      public void DeleteObject(object obj)
      {
         ITransaction trn = this._activeSession.BeginTransaction();
         try
         {
            this._activeSession.Delete(obj);
            trn.Commit();
         }
         catch (Exception ex)
         {
            trn.Rollback();
            throw ex;
         }
      }
      /// <summary>
      /// Mark an object for deletion. Commit the deletion with Session.Flush.
      /// </summary>
      /// <param name="obj"></param>
      public void MarkForDeletion(object obj)
      {
         this._activeSession.Delete(obj);
      }
      #endregion
   }
}
Code:
<<<< SessionFactory class >>>>
using System;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;
namespace NHibernateHelper
{
   /// <summary>
   /// The SessionFactory provides the NHibernate sessions and provides the possibility to register
   /// additional classes with NHibernate by modules.
   /// </summary>
   public class SessionFactory
   {
      private static SessionFactory __sessionFactory = null;
      
      private static SessionFactory _sessionFactory(System.Collections.IDictionary properties, Assembly assembly)
      {
         if(SessionFactory.__sessionFactory == null) SessionFactory.__sessionFactory = new SessionFactory(properties, assembly);
         return SessionFactory.__sessionFactory;
      }
      
      private Configuration _nhibernateConfiguration;
      private ISessionFactory _nhibernateFactory;
      private bool _classesAdded = false;
      /// <summary>
      /// Default constructor.
      /// </summary>
      protected SessionFactory(System.Collections.IDictionary properties, Assembly assembly)
      {
         RegisterClasses( properties, assembly );
      }
      /// <summary>
      /// Gets the one instance of the SessionFactory. This is done with a singleton so we don't have
      /// to register mappings etc. with every request.
      /// </summary>
      /// <returns></returns>
      public static SessionFactory GetInstance(System.Collections.IDictionary properties, Assembly assembly)
      {
         return _sessionFactory( properties, assembly );
      }
      /// <summary>
      /// GetNHibernateFactory returns the current NHibernate ISessionFactory.
      /// </summary>
      public ISessionFactory GetNHibernateFactory()
      {
         return this._nhibernateFactory;
      }
      /// <summary>
      /// Get a new NHibernate session.
      /// </summary>
      /// <returns></returns>
      public ISession GetSession()
      {
         return this._nhibernateFactory.OpenSession();
      }
      /// <summary>
      /// Add a class to the NHibernate mappings.
      /// If the class already is mapped, nothing will happen. 
      /// </summary>
      /// <param name="type"></param>
      public void RegisterPersistentClass(Type type)
      {
         if (this._nhibernateConfiguration.GetClassMapping(type) == null)
         {
            // Class isn't mapped yet, so do it now.
            this._nhibernateConfiguration.AddClass(type);
            this._classesAdded = true;
         }         
      }
      /// <summary>
      /// Rebuild the NHibernate ISessionFactory. Use it after registering new classes.
      /// </summary>
      public bool Rebuild()
      {
         // Rebuild NHibernate SessionFactory to activate the new mapping.
         if (this._classesAdded)
         {
            this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
            this._classesAdded = false;
            return true;
         }
         else
         {
            return false;
         }
      }
      private void RegisterClasses(System.Collections.IDictionary properties, Assembly assembly )
      {
         Configuration config = new Configuration();
         config.AddProperties(properties);
         this._nhibernateConfiguration = config.AddAssembly( assembly );
         this._nhibernateFactory = this._nhibernateConfiguration.BuildSessionFactory();
      }
   }
}