nhibernate : a different object with the same identifier value was already associated with the session: 2, of entity:

前端 未结 5 2036
陌清茗
陌清茗 2021-01-01 11:40

I am getting the following error when i tried and save my \"Company\" entity in my mvc application

a different object with the same identifier value was alre

相关标签:
5条回答
  • 2021-01-01 11:49

    I just encountered this and Claiton Lovato's answer didn't work. However Iko's did work. Here's a little more robust version of Iko's. Downside is x2 trips to the db - one for the Get and another for the insert/update.

    A possible solution to this is to read the object from the database, copy the fields to the object, and save it.

    public void Save(Company company)
    {
    
        Company dbCompany = null;
        //update
        if (company.Id != 0)
        {
            dbCompany = _companyRepository.Get(company.Id);
            dbCompany.PropertyToUpdate = company.PropertyToUpdate;
        }
        //insert
        else
        {
            dbDefaultFreightTerm = company;
        }
        // Save either the brand new object as an insert
        // Or update the original dbCompany object with an update
        _companyRepository.SaveOrUpdate(company);
    }
    
    0 讨论(0)
  • 2021-01-01 11:51

    I know this is a bit late and you might already found the solution, but maybe others could benefit from it...

    This error is raised from nHibernate when you are updating an instance of an Entity that is saved on the Cache. Basically nHibernate stores your objects on the cache once you loaded it, so next calls would get it from the cache. If you update an instance that is present on the cache nHibernate throws this error otherwise it could cause dirty reads and conflicts regarding loading the old copy of the object. To get around this, you need to remove the object from the cache using the Evict method like:

    public ActionResult Edit(EStore.Domain.Model.Company company) 
    { 
    
            if (company.Id > 0) 
            { 
                **ISession.Evict(company);**
                _companyRepository.Update(company);
    

    Hope this helps.

    0 讨论(0)
  • 2021-01-01 12:04

    A possible solution to this is to read the object from the database, copy the fields to the object, and save it. NHibernate session doesn't know anything about the incoming object which was instantiated by an MVC Model Binder.

    In certain cases the whole object may not be visible or passed to the View/ViewModel. When saving it should first be read from NHibernate, then updated and saved.

    Company cOrig = _companyRepository.Get(company.Id);
    cOrig.PropertyToUpdate = company.PropertyToUpdate;
    ... // Copy the properties to be updated.
    // Save the freshly retrieved object! 
    // Not the new object coming from the View which NHibernate Session knows nothing about.
    _companyRepository.Update(cOrig);
    

    This requires parsing/mapping the ViewModel/Class properties to the Domain Model/Class, but in many cases you don't necessarily present them all to be updated in the view so you would need to do it anyway (Can't save partially empty objects on top of old objects).

    0 讨论(0)
  • 2021-01-01 12:05

    I tried @claitonlovatojr's hack, but I couldn't still handle the error.

    All I had to do in my case wasy to replace my ISession.Update(obj) call to ISession.Merge(obj).

    In your repository, change:

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

    Also, for more information see this answer.

    0 讨论(0)
  • 2021-01-01 12:07

    for more agrgessive way you can use the Clear() method

    0 讨论(0)
提交回复
热议问题