2010-06-06 8 views
20

Ben çalıştığımızda aşağıdaki hatayı alıyorum ve benim mvc uygulamada benim "Şirket" varlık kaydetmeye amnhibernate: Aynı tanımlayıcı değerle farklı nesne zaten oturum ile ilişkili bulunmuştur: 2, varlığın:

aynı tanımlayıcı değerle farklı nesne zaten oturum ile ilişkili bulunmuştur: 2, varlığın: Ben IOC konteyner

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

      Bind<ICompanyRepository>().To<CompanyRepository>().WithConstructorArgument("session", 
                         NHibernateHelper.OpenSession()); 
     } 
    } 

My CompanyRepository kullanıyorum

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(); 
     } 
    } 

}

Ve Oturum Yardımcısı

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; 
     } 
    } 
} 

My MVC Eylem bildiğim

[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); 
    } 
+0

Sorun bir birim testinde yeniden üretebilir mi? –

cevap

32

bunu biraz geç olduğunu ve zaten çözümü, ama belki başkalarını bulundu olabilir bundan yararlanabilir ...

Bu Önbelleğe kaydedilen bir Varlığın örneğini güncelleştirirken nHibernate'ten hata alınır. Temel olarak nHibernate, yükledikten sonra nesnelerinizi önbellekte depolar, böylece sonraki aramalar önbellekten alır. Önbellekte bulunan bir örneği güncellerseniz, bu hatayı atar, aksi takdirde nesnenin eski kopyasının yüklenmesiyle ilgili kirli okumalara ve çakışmalara neden olabilir. Bu yardımcı olur

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

     if (company.Id > 0) 
     { 
      **ISession.Evict(company);** 
      _companyRepository.Update(company); 

Hope: Bundan kaçınmak için, gibi çıkar'ı yöntemi kullanarak önbellekten nesneyi kaldırmak gerekir.

+2

Merhaba, bunu yanıtladığınız için teşekkür ederim, Aslında sizin için gerçekten kötü hazırlanmış bir soru. Benim varlığımdan birinin, yukarıdaki açıklamanızla ilişkili olan aynı oturumu kullanmadığını ortaya çıkarır. – frosty

+9

Bu bir kesmek. Bahse girerim ki, önceki oturumu düzgün bir şekilde kapatıp kapatmazsınız. –

+1

Sorun, NHibernate'in yeni oluşturulan nesneyi (NHibernate Session dışında) tanımaması gibi görünüyor. Cevabımı gör. – lko

1

daha agrgessive şekilde sen Clear() yöntemini

+4

Bu, bekleyen tüm işlem değişikliklerini temizler. – gwin003

3

Bu olası bir çözüm veritabanından nesne okumaktır kullanmak nesneye alanları kopyalamak ve kaydedebilirsiniz için. NHibernate oturumu, bir MVC Model Binder tarafından başlatılan gelen nesne hakkında bir şey bilmiyor.

Bazı durumlarda, tüm nesne görünmeyebilir veya View/ViewModel'e iletilmeyebilir. Kaydetirken ilk olarak NHibernate'den okunmalı, ardından güncellenmeli ve kaydedilmelidir. Eğer yine de yapmak gerekir bu yüzden

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); 

Bu ayrıştırma/Alan Modeli/Class ViewModel/Sınıf özelliklerini haritalama, ancak birçok durumda mutlaka hepsini ibraz etmeyen gerektirir görünümde güncellenmesi (Kısmen boş nesneleri eski nesnelerin üzerine kaydedemez).

8

@ claitonlovatojr hack'i denedim, ancak hatayı hala halledemedim.

Tek yapmam gereken şey, ISession.Update(obj) numaramı ISession.Merge(obj) numaralı telefonumun yerine koymaktı. senin depo olarak

, değişim:

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

Ayrıca, daha fazla bilgi için this answer bakın.

İlgili konular