当前位置:编程学习 > C#/ASP.NET >>

关于 NHibernate 的Session问题

鄙人不才,望大牛指点!
HibernateSessionManager :用于管理NHibernate的Session。
NHibernateDALBase:封装的数据访问层。

当设置HibernateSessionManager的属性: autoCloseSession = false时:
更新或保存实体是有异常信息,但不一定每次出现:
在 NHibernateDAL.NHibernateDALBase.Update(Object persistentObject) 
抛出异常:[NHibernate.NonUniqueObjectException] = {"a different object with the same identifier value was already associated with the session: d06a2cd29f714124944f71be94549b3e, of entity:......"}
本人试过将session merge,但还是出错!

当设置HibernateSessionManager的属性: autoCloseSession = true时:
调试时不会出现异常,运行环境中NHibernateDALBase访问数据库是就会出现以下异常 :
异常信息: 
    异常类型: ObjectDisposedException 
    异常消息: 无法访问已释放的对象。
对象名:“AdoTransaction”。 
堆栈跟踪:    在 NHibernate.Transaction.AdoTransaction.CheckNotDisposed()
   在 NHibernate.Transaction.AdoTransaction.Commit()
   在 NHibernateDAL.HibernateSessionManager.CommitTransaction()
   在 NHibernateDAL.NHibernateDALBase.CommitTransaction()
   在 NHibernateDAL.NHibernateDALBase.Save(Object persistentObject)



HibernateSessionManager代码如下:
  
sealed class HibernateSessionManager
    {
        [ThreadStatic]
        private static ISessionFactory sessionFactory;

        [ThreadStatic]
        private static ISession session;

        [ThreadStatic]
        private static ITransaction transaction;

        [ThreadStatic]
        private static HibernateSessionManager instance;

        /// <summary>
        /// Private empty constructor. Cannot be used to create instance. 
        /// Call static methods GetInstance directly.
        /// </summary> 
        private HibernateSessionManager()
        {
            Configuration cfg = new Configuration();
            cfg.Configure(Assembly.Load("NHibernateDAL"), "NHibernateDAL.hibernate.cfg.xml");

            sessionFactory = cfg.BuildSessionFactory();
        }

        public static HibernateSessionManager GetInstance()
        {
            if (instance == null)
            {
                instance = new HibernateSessionManager();
            }
            return instance;
        }

        /// <summary>
        /// Get the session factory.
        /// </summary> 
        public ISessionFactory GetSessionFactory()
        {
            return sessionFactory;
        }

        /// <summary>
        /// Get the session factory.
        /// </summary> 
        public ISessionFactory SetSessionFactory(ISessionFactory sf)
        {
            sessionFactory = sf;
            return sessionFactory;
        }

        /// <summary>
        /// Get session associated with current thread. Create new one from session
        /// factory if no session is found and openSession is true.
        /// </summary>
        public ISession GetSession(bool openSession)
        {
            if (openSession)
            {
                try
                {
                    if (session == null)
                    {
                        session = sessionFactory.OpenSession();
                    }
                }
                catch (HibernateException ex)
                {
                    throw new DALException("Fail to open session", ex);
                }
            }
            return session;
        }

        /// <summary>
        /// Set new session associated with current thread. Return old session.
        /// </summary>
        public ISession SetSession(ISession s)
        {
            session = s;
            return session;
        }

        /// <summary>
        /// Close session associated with current thread if exists.
        /// </summary>
        public void CloseSession()
        {
            try
            {
                if (session != null && session.IsOpen)
                {
                    session.Close();
                }
                session = null;
            }
            catch (HibernateException ex)
            {
                throw new DALException("Fail to open session", ex);
            }
        }

        /// <summary>
        /// Begin the transaction associated with current thread. Begin new one from
        /// session associated with current thread if no transaction is found.
        /// </summary>
        public void BeginTransaction()
        {
            try
            {
                if (transaction == null)
                {
                    transaction = GetSession(true).BeginTransaction();
                }
            }
            catch (HibernateException ex)
            {
                throw new DALException("Fail to begin transaction", ex);
            }
        }

        /// <summary>
        /// Commit the transaction associated with current thread.
        /// </summary>
        public void CommitTransaction()
        {
            try
            {
                if (transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack)
                    transaction.Commit();
                transaction = null;
            }
            catch (HibernateException ex)
            {
                RollbackTransaction();
                throw new DALException("Fail to commit transaction", ex);
            }
        }

        /// <summary>
        /// Rollback transaction associated with current thread. Close session in the end.
        /// </summary>
        public void RollbackTransaction()
        {
            try
            {
                if (transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack)
                {
                    transaction.Rollback();
                }
                transaction = null;
            }
            catch (HibernateException ex)
            {
                throw new DALException("Fail to rollback transaction", ex);
            }
            finally
            {
                CloseSession();
            }
        }

    }



--------------------编程问答-------------------- NHibernateDALBase部分代码:
 public class NHibernateDALBase : IDALBase
    {
        private bool autoCommit = true;

        private bool autoCloseSession = false;

        private bool cacheQueries = false;

        private string queryCacheRegion = null;

        public NHibernateDALBase()
        {

        }

        public bool AutoCloseSession
        {
            get
            {
                return this.autoCloseSession;
            }
            set
            {
                this.autoCloseSession = value;
            }
        }

        /// <summary>
        /// Get the current session factory
        /// </summary>
        public ISessionFactory GetSessionFactory()
        {
            return HibernateSessionManager.GetInstance().GetSessionFactory();
        }

        /// <summary>
        /// Set the current session factory
        /// </summary>
        public void SetSessionFactory(ISessionFactory sessionFactory)
        {
            HibernateSessionManager.GetInstance().SetSessionFactory(sessionFactory);
        }

        /// <summary>
        /// Set the current session
        /// </summary>
        public ISession SetSession(ISession session)
        {
            return HibernateSessionManager.GetInstance().SetSession(session);
        }

        /// <summary>
        /// Get the current session. 
        /// If the openSession is true and the current session is not opened, the session will be opened automatically.
        /// </summary>
        public ISession GetSession(bool openSession)
        {
            return HibernateSessionManager.GetInstance().GetSession(openSession);
        }

        /// <summary>
        /// Get the current session.         
        /// </summary>
        public ISession GetSession()
        {
            return GetSession(false);
        }

        /// <summary>
        /// Close the current session. 
        /// </summary>
        public void CloseSession()
        {
            HibernateSessionManager.GetInstance().CloseSession();
        }

        /// <summary>
        /// Flush the current session. 
        /// </summary>
        public void FlushSession()
        {
            if (GetSession() != null)
            {
                try
                {
                    GetSession().Flush();
                }
                catch (HibernateException e)
                {
                    throw new DALException("Fail to flush session", e);
                }
            }
        }

        /// <summary>
        /// Clear the current session. 
        /// </summary>
        public void ClearSession()
        {
            if (GetSession() != null)
            {
                try
                {
                    GetSession().Clear();
                }
                catch (HibernateException ex)
                {
                    throw new DALException("Fail to clear session", ex);
                }
            }
        }

        /// <summary>
        /// Open the session        
        /// </summary>
        private ISession OpenSession()
        {
            return GetSession(true);
        }

        /// <summary>
        /// Start a transaction        
        /// </summary>
        public void BeginTransaction()
        {
            HibernateSessionManager.GetInstance().BeginTransaction();
        }

        /// <summary>
        /// Commit current transaction        
        /// </summary>
        public void CommitTransaction()
        {
            HibernateSessionManager.GetInstance().CommitTransaction();
        }

        /// <summary>
        /// Rollback current transaction        
        /// </summary>
        public void RollbackTransaction()
        {
            HibernateSessionManager.GetInstance().RollbackTransaction();
        }

        /// <summary>
        /// Check whether to commit a transaction automatically or not.
        /// </summary>
        public bool IsAutoCommit()
        {
            return this.autoCommit;
        }

        /// <summary>
        /// Set a transaction commit style to automatic, 
        /// i.e., transaction in each CRUD methods will automatically commited.
        /// </summary>
        public void SetAutoCommit(bool autoCommit)
        {
            this.autoCommit = autoCommit;
        }

        /// <summary>
        /// Get current DbConnection
        /// </summary>
        public IDbConnection GetConnection()
        {
            if (GetSession() != null && GetSession().IsConnected)
                return GetSession().Connection;
            return null;
        }

        public int FindCount(Type type, IList restrictions)
        {
            ISession session = this.OpenSession();
            int ireturn = 0;
            try
            {
                BeginTransaction();
                ICriteria criteria = session.CreateCriteria(type);
                foreach (ICriterion criterion in restrictions)
                {
                    criteria.Add(criterion);
                }
                ireturn = (Int32)criteria.SetProjection(Projections.RowCount()).UniqueResult();

            }
            catch (HibernateException ex)
            {
                throw new DALException("Fail to load all", ex);
            }
            finally
            {
                if (autoCloseSession)
                    CloseSession();
            }
            return ireturn;
        }
        /// <summary>
        /// Close current DbConnection
        /// </summary>
        public void CloseConnection()
        {
            if (GetSession() != null)
            {
                try
                {
                    GetSession().Connection.Close();
                }
                catch (Exception ex)
                {
                    throw new DALException("Fail to close connection", ex);
                }
                finally
                {
                    if (autoCloseSession)
                        CloseSession();
                }
            }
        }

        /// <summary>
        /// Update the persistentObject to the database.
        /// </summary>
        public void Update(object persistentObject)
        {
            try
            {
                ISession session = OpenSession();
                BeginTransaction();
                session.Update(persistentObject);
                if (autoCommit)
                    CommitTransaction();
                session.Refresh(persistentObject, LockMode.Upgrade);
            }
            catch (HibernateException ex)
            {
                RollbackTransaction();
                throw new DALException("Fail to update", ex);
            }
            finally
            {
                if (autoCloseSession)
                    CloseSession();
            }
        }

        /// <summary>
        /// Delete the persistentObject to the database.
        /// </summary>
        public void Delete(object persistentObject)
        {
            try
            {
                ISession session = OpenSession();
                BeginTransaction();
                session.Delete(persistentObject);

                if (autoCommit)
                    CommitTransaction();
            }
            catch (HibernateException ex)
            {
                RollbackTransaction();
                throw new DALException("Fail tlo delete", ex);
            }
            finally
            {
                if (autoCloseSession)
                    CloseSession();
            }
        }

        /// <summary>
        /// Check whether current queries are cached or not.
        /// </summary>
        public bool IsCacheQueries()
        {
            return cacheQueries;
        }

        /// <summary>
        /// Get the region of cached query.
        /// </summary>
        public string GetQueryCacheRegion()
        {
            return queryCacheRegion;
        }

        /// <summary>
        /// SaveOrUpdate the persistent objec to the database.
        /// </summary>
        public void SaveOrUpdate(object persistentObject)
        {
            try
            {
                ISession session = this.OpenSession();
                BeginTransaction();
                session.SaveOrUpdate(persistentObject);
                if (autoCommit)
                    CommitTransaction();
                session.Refresh(persistentObject, LockMode.Upgrade);
            }
            catch (HibernateException ex)
            {
                RollbackTransaction();
                throw new DALException("Fail to save or update persistentObject", ex);
            }
            finally
            {
                if (autoCloseSession)
                    CloseSession();
            }
        }

        /// <summary>
        /// Get all instances according to query statement.
        /// </summary>
        public IList Find(string queryString)
        {
            return Find(queryString, (object[])null);
        }

    }
补充:.NET技术 ,  其他语言
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,