2010-09-20 27 views
0

我在NHibernate中收到「保存未保存的瞬態實體」錯誤。我有一個聚合根,neighborhood包含addressesperson,這裏的一些快速的僞代碼解釋關係:一次在NHibernate中保存多個子實體

public class Neighborhood { 
    public virtual int Id { get; set; } 
    public virtual IList<Address> Addresses { get; set; } 
} 

public class Address { 
    public virtual int Id { get; set; } 
    public virtual string Address { get; set; } 
    public virtual Person Person { get; set; } //Assume only one person per address 
} 

public class Person { 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

在我家附近的地圖,我有:

mapping.HasMany(x => x.Addresses) 
     .Inverse() 
     .KeyColumn("NeighborhoodFk") 
     .Cascade.All() 
     .AsBag(); 

在我的代碼我會經常想要創建並同時關聯Address和Person:

var address = new Address(); 
var person = new Person(); 

var address.Person = person; 

var neighborhood = neighborhoodRepository.Get(id); 

neighborhood.Add(address); 

neighborhoodRepository.DbContext.BeginTransaction(); 
neighborhoodRepository.SaveOrUpdate(neighborhood); 
neighborhoodRepository.DbContext.CommitTransation(); 

我將得到「未保存的瞬態實體「錯誤Person實體,因爲它連接到瞬態實體Address

我可以解決此看到的唯一方法是保存address第一,對數據庫進行另一個呼叫更新後更新neighborhood,搜索我剛添加的address,附加person,然後再保存。

有什麼我錯過,使這更容易?這看起來像是一個常見的用例,我不想爲數據庫做大量的往返操作。

回答

5

確保您將地址映射到人員的「級聯」屬性設置爲「save-update」或「all」。你有從鄰里到地址的級聯,但你沒有聲明這個較低級聯存在。如果不是,你得到這個錯誤不是因爲一個Person被附加到一個臨時地址,而是因爲該地址引用了一個臨時Person。

如果無論出於何種原因無法制作此級聯,請首先保存Person,然後保存將級聯到地址的鄰居,然後ORM將在其會話中找到引用的Person並設置引用。這可能會導致一些額外的「往返行程」,具體取決於您是讓NH還是DB生成自動編號列。 NHibernate很棘手,因爲它會在數據庫調用良好並準備好時進行數據庫調用,這可能是在整個對象圖處於NH會話中之後,或者只是人。無論哪種方式,它將爲每個持久化對象創建一個Insert調用,因此無論將項添加到會話的代碼是什麼樣子,都會產生多次「往返」。

+0

我錯過了第二個Cascade All,謝謝! – 2010-09-20 18:01:24

相關問題