关于 NHibernate 的Session问题

cc850516 2013-01-12 10:40:42
鄙人不才,望大牛指点!
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();
}
}

}



...全文
508 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
cc850516 2013-01-12
  • 打赏
  • 举报
回复
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);
        }

    }

1,979

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 其他语言讨论
社区管理员
  • 其他语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧