关于 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技术 , 其他语言