我有一个非常奇怪的问题:从Web用户控件调用时,NHibernate会崩溃。
我正在开发一个使用NHibernate访问数据库的ASP.Net(2.0)网页。
我有一个简单的工厂类来访问表ProjectInfo中的列CurrentStepNumber:
public class ProjectEntity
{
private int? _currentStepNumber;
public virtual int? CurrentStepNumber
{
get { return _currentStepNumber; }
set { _currentStepNumber = value; }
}
public static ProjectWizardEntity GetById(int id, bool shouldLock)
{
return RepositoryFactory.ProjectWizardRepository.GetById(id, shouldLock);
}
public static ProjectWizardEntity GetById(int id)
{
return GetById(id, false);
}
public virtual void Save()
{
RepositoryFactory.ProjectWizardRepository.Save(this);
}
public virtual void SaveOrUpdate()
{
RepositoryFactory.ProjectWizardRepository.SaveOrUpdate(this);
}
}
通过代理类访问此类,以便每次分配新值时,都会刷新到数据库:
public class DBHelper
{
ProjectEntity _projectEntity;
ProjectEntity GetProjectEntity()
{
if (_projectEntity == null)
_projectEntity = //get or create a new one;
return _projectEntity ;
}
public int? CurrentStepNumber
{
get
{
return (CurrentProjectId > 0) ? CurrentProjectWizardEntity.CurrentStepNumber : 0;
}
set
{
if (CurrentProjectId > 0)
{
CurrentProjectWizardEntity.CurrentStepNumber = value;
CurrentProjectWizardEntity.SaveOrUpdate();
}
}
}
}
现在出现问题:
NHibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话相关联
实际上NHibernate Repository的 SaveOrUpdate 方法会引发异常。
我无法弄清楚这里可能出现什么问题,所以任何帮助都会受到赞赏。
答案 0 :(得分:0)
我认为您在这里遇到会话管理问题。 RepositoryFactory.ProjectWizardRepository.GetById如何创建并可能处理NHibernate会话?它会创建然后关闭会话吗?
似乎DBHelper.GetProjectEntity()正在创建或加载ProjectEntity。稍后,当我调用CurrentStepNumber的setter时,您将对象插入或更新到数据库。
问题在于,当DBHelper.GetProjectEntity()正在加载现有对象并稍后在加载后关闭会话但保持对象时,我们正在进入深水区。稍后更新对象时,为CurrentStepNumber设置新值并将对象发送到NHibernate进行保存。这里的问题是该对象与保存期间创建和关闭的新会话无关。然后Nhibernate会因为发现一个未从当前会话加载但它具有现有对象id的新对象而感到困惑。
对于一个解决方案,谷歌的“NHibernate asp.net会话管理”,你将获得一些关于如何使用ASP.NET请求周期作为一个工作单元的好点击。