2017-07-06 3 views
1

ich mit einem NHibernate Problem bin rang ich nie in den Ruhezustand hatte. Ich habe ein Objekt mit einer faulen geladenen Sammlung. Ich lade das Objekt in einer Sitzung hoch und möchte es dann in einer anderen Sitzung wieder anfügen und die lazy loaded-Sammlung initialisieren. Allerdings bekomme ich immer einen Fehler "Sammlung ist nicht mit einer Sitzung verbunden". Der Code zu fusionieren ist sehr einfach:Merge Freistehendes Objektgraph in 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); 
       } 
      }); 
     } 
    } 

Der Merge aber das Initialisieren Aufruf ausführt wirft die ‚nicht mit einem Sitzungsfehler assoziiert‘ - beachten Sie, dass ich auf Hibernate 3 bin (durch eine Abhängigkeit von Active verriegelt an der Moment). Ich hätte gedacht, dass das Merge das sampleType-Objekt und seine Sammlung neu zuordnen würde?

Kann jemand bitte etwas Licht auf die Situation für mich vergossen? Beachten Sie, dass ich die ganze Sache (einschließlich der faulen Sammlung) in einer Sitzung laden kann, aber ich muss wissen, wie man eine Sammlung für NHibernate im Allgemeinen neu anbringt und lazy lädt.

Cheers,

Neil

Antwort

1

Merge ist für freistehende Entitätsobjekt in das entsprechende andere Objekt aus der zweiten Sitzung zu kopieren. Dieses entsprechende Objekt in der zweiten Sitzung wird dann von Merge zurückgegeben.

Ihr freistehendes Objekt ist noch danach abgelöst.

Ihr Code würde nicht abstürzen, wenn Sie tun:

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

Dies ist in den Merge xml Kommentaren (Hervorhebung von mir) dokumentiert.

Kopieren Sie den Status des angegebenen Objekts auf das persistente Objekt mit demselben Bezeichner. Wenn der Sitzung derzeit keine persistente Instanz zugeordnet ist, wird sie geladen. Gibt die persistente Instanz zurück. Wenn die angegebene Instanz nicht gespeichert ist, speichern Sie eine Kopie von und geben Sie sie als neu persistente Instanz zurück. Die angegebene Instanz wird nicht mit der Sitzung verknüpft.

Vielleicht passt das nicht zu Ihnen. Wenn Sie möchten, dass Ihr losgelöstes Objekt der zweiten Sitzung zugeordnet wird, müssen Sie in dieser zweiten Sitzung Update. Zugegeben, die Update XML-Kommentare sind nicht explizit darüber. Vorsicht (von <remarks>):

Wenn es eine persistente Instanz mit dem gleichen Bezeichner gibt, wird eine Ausnahme ausgelöst.

Das bedeutet, wenn die zweite Sitzung bereits dieselbe Entität geladen hat, wird Update fehlschlagen.

+0

Danke; in der Tat habe ich herausgefunden, dass die Zusammenführung ein Objekt zurückgibt und _that_ das zusammengeführte Objekt ist, das Sie dann verwenden können, wie Sie es geschrieben haben. Der Update-Trick ist jedoch wissenswert, da ich das nicht erkannt habe. Alles, was ich jetzt tun muss, ist den Activecord wegwerfen und auf NHibernate 4 upgraden! –

+0

Dies ist kein "Update-Trick", das ist der Anwendungsfall für Updates. 'Update' ist für angehängte Entitäten nicht notwendig, ihre werden nach Änderungen von der Sitzung verfolgt, die Sitzung benötigt keinen 'Update'-Aufruf für sie. 'Aktualisieren' ist nur für getrennte Entitäten oder Entitäten nützlich, die von einer anderen Sitzung kommen. –

+0

Ich weiß, es ist kein Trick; das war Umgangssprache! –