2017-07-06 159 views
1

我正在嘲笑我在Hibernate中從未有過的NHibernate問題。我有一個延遲加載集合的對象。我在一個會話中加載對象,然後我想在另一個會話中重新掛接它並初始化延遲加載的集合。不過,我一直收到一個'集合與會話沒有關聯'的錯誤。合併的代碼非常簡單:在NHibernate中合併獨立對象圖

/// <summary> 
    /// Loads all the lazy collections in the sample types 
    /// </summary> 
    /// <param name="sampleTypes"></param> 
    public static void FullyLoadSampleTypes(ICollection<SampleType> sampleTypes) 
    { 
     using (SessionScopeWrapper ssw = new SessionScopeWrapper(FlushAction.Never)) 
     { 
      sampleTypes.ForEach(st => 
      { 
       if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs)) 
       { 
        ssw.Session.Merge(st); 
        NHibernateUtil.Initialize(st.MasterKeyValuePairs); 
       } 
      }); 
     } 
    } 

合併執行,但初始化調用拋出了「不與會話錯誤關聯」 - 注意,我在休眠3(通過對ActiveRecord的依賴鎖定此時此刻)。我會認爲合併會重新關聯sampleType對象,它是集合?

任何人都可以請給我介紹一下情況嗎?請注意,我可以在一個會話中加載整個事件(包括惰性集合),但我需要知道如何重新附加和延遲加載NHibernate的集合。

乾杯,

尼爾

回答

1

Merge是複製你脫離實體對象到從第二屆相應的其他對象。進入第二次會話的相應對象然後由Merge返回。

您的分離對象之後仍然分離。

您的代碼不會崩潰,如果你在做:

if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs)) 
{ 
    var merged = ssw.Session.Merge(st); 
    NHibernateUtil.Initialize(merged.MasterKeyValuePairs); 
} 

這在Merge XML註釋(重點煤礦)進行了說明。

將給定對象的狀態複製到具有相同標識符的持久對象上。如果當前沒有與會話關聯的持久實例,則會加載它。返回持久化實例。如果給定實例未保存,則保存一個副本並將其作爲新的持久實例返回。 給定實例不會與會話關聯。

也許這不適合你。如果您希望將分離的對象與第二個會話關聯,則需要在第二個會話中使用Update。當然,Update xml註釋並不明確。請注意(<remarks>):

如果存在具有相同標識符的持久實例,則會引發異常。

這意味着如果你的第二個會話已經加載了相同的實體,Update將失敗。

+0

謝謝;事實上,我發現合併會返回一個對象,_that_是合併的對象,然後您可以像剛剛寫入的那樣使用它。更新技巧是值得了解的,但我沒有意識到這一點。我現在要做的就是扔掉主動記錄並升級到NHibernate 4! –

+0

這不是一個「更新技巧」,這是更新用例。 'Update'對於連接的實體是不需要的,它們通過會話進行跟蹤以獲得更改,會話不需要對它們進行任何'Update'調用。 'Update'僅適用於來自另一個會話的分離實體或實體。 –

+0

我知道這不是一招;那是口語化的講話! –