从ASP.Net中的Web用户控件调用时,NHibernate崩溃

时间:2009-01-28 15:30:15

标签: asp.net nhibernate controls

我有一个非常奇怪的问题:从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();
        }
    }
}
}

现在出现问题:

  1. 当我从test.aspx页面访问 CurrentStepNumber 时,一切运作正常
  2. 当我从test.aspx页面上使用的Web用户控件(test.ascx)读取此字段时,它仍然可以
  3. 然而当我尝试在控件(test.ascx)后面的代码中为 CurrentStepNumber 分配值时,我总是会遇到异常:
  4.   

    NHibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已与会话相关联

    实际上NHibernate Repository的 SaveOrUpdate 方法会引发异常。

    我无法弄清楚这里可能出现什么问题,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我认为您在这里遇到会话管理问题。 RepositoryFactory.ProjectWizardRepository.GetById如何创建并可能处理NHibernate会话?它会创建然后关闭会话吗?

似乎DBHelper.GetProjectEntity()正在创建或加载ProjectEntity。稍后,当我调用CurrentStepNumber的setter时,您将对象插入或更新到数据库。

问题在于,当DBHelper.GetProjectEntity()正在加载现有对象并稍后在加载后关闭会话但保持对象时,我们正在进入深水区。稍后更新对象时,为CurrentStepNumber设置新值并将对象发送到NHibernate进行保存。这里的问题是该对象与保存期间创建和关闭的新会话无关。然后Nhibernate会因为发现一个未从当前会话加载但它具有现有对象id的新对象而感到困惑。

对于一个解决方案,谷歌的“NHibernate asp.net会话管理”,你将获得一些关于如何使用ASP.NET请求周期作为一个工作单元的好点​​击。