nhibernate:具有相同标识符值的不同对象已与会话关联:2,实体:

fro*_*sty 24 nhibernate asp.net-mvc

当我尝试将我的"公司"实体保存在我的mvc应用程序中时,我收到以下错误

具有相同标识符值的不同对象已与会话关联:2,实体:

我正在使用IOC容器

private class EStoreDependencies : NinjectModule
    {
        public override void Load()
        {

            Bind<ICompanyRepository>().To<CompanyRepository>().WithConstructorArgument("session",
                                                                                       NHibernateHelper.OpenSession());
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的CompanyRepository

public class CompanyRepository : ICompanyRepository
{
    private ISession _session;

    public CompanyRepository(ISession session)
    {
        _session = session;
    }    

    public void Update(Company company)
    {

        using (ITransaction transaction = _session.BeginTransaction())
        {

            _session.Update(company);
            transaction.Commit();
        }
    }
Run Code Online (Sandbox Code Playgroud)

}

和会话助手

public class NHibernateHelper
{
    private static ISessionFactory _sessionFactory; 
    const string SessionKey = "MySession";


    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
            {
                var configuration = new Configuration();
                configuration.Configure();
                configuration.AddAssembly(typeof(UserProfile).Assembly);
                configuration.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName,
                                          System.Environment.MachineName);
                _sessionFactory = configuration.BuildSessionFactory();
            }
            return _sessionFactory;
        }
    }

    public static ISession OpenSession()
    {
        var context = HttpContext.Current;
        //.GetCurrentSession()

        if (context != null && context.Items.Contains(SessionKey))
        {
            //Return already open ISession
            return (ISession)context.Items[SessionKey];
        }
        else
        {
            //Create new ISession and store in HttpContext
            var newSession = SessionFactory.OpenSession();
            if (context != null)
                context.Items[SessionKey] = newSession;

            return newSession;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的MVC行动

    [HttpPost]
    public ActionResult Edit(EStore.Domain.Model.Company company)
    {

            if (company.Id > 0)
            {

                _companyRepository.Update(company);
                _statusResponses.Add(StatusResponseHelper.Create(Constants
                    .RecordUpdated(), StatusResponseLookup.Success));
            }
            else
            {
                company.CreatedByUserId = currentUserId;
               _companyRepository.Add(company);
            }


        var viewModel = EditViewModel(company.Id, _statusResponses);
        return View("Edit", viewModel);
    }
Run Code Online (Sandbox Code Playgroud)

Cla*_*ato 37

我知道这有点晚了你可能已经找到了解决方案,但也许其他人可以从中受益......

当您更新保存在高速缓存上的实体实例时,会从nHibernate引发此错误.基本上,nHibernate在加载后将对象存储在缓存中,因此下一次调用将从缓存中获取它.如果更新缓存中存在的实例,则nHibernate会抛出此错误,否则可能导致脏读取和有关加载对象的旧副本的冲突.要解决此问题,您需要使用Evict方法从缓存中删除对象,如:

public ActionResult Edit(EStore.Domain.Model.Company company) 
{ 

        if (company.Id > 0) 
        { 
            **ISession.Evict(company);**
            _companyRepository.Update(company);
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 这是一个黑客.我打赌问题是你没有正确刷新和关闭前一个会话. (11认同)
  • 嗨,谢谢你的回复,实际上是你真正的一个糟糕起草的问题.事实证明我的一个实体没有使用与您上面的解释相关的相同会话. (2认同)

Joe*_*oel 11

我试过@ claitonlovatojr的黑客,但我仍然无法处理错误.

在我的情况下,我所要做的就是取代我的ISession.Update(obj)电话ISession.Merge(obj).

在您的存储库中,更改:

public void Update(Company company)
{
    using (ITransaction transaction = _session.BeginTransaction())
    {
        //_session.Update(company);
        _session.Merge(company); // <-- this
        transaction.Commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,有关更多信息,请参阅此答案.