2010-12-08 3 views
8

Ich erhalte den folgenden Fehler auf unserer Produktion Webserver:NHibernate LazyInitializationException .. Wie zu verhindern?

NHibernate.LazyInitializationException 
: 
Initializing[Domain.Entities.AudienceTypes.Region#4]-failed to lazily initialize a 
collection of role: Domain.Entities.AudienceTypes.Region.PeerGroups, 
no session or session was closed 

, die nicht gut ist. Die einzige Möglichkeit, die Anwendung wieder zum Laufen zu bringen, ist das Zurücksetzen von IIS, was eigentlich keine Option ist. Was bedeutet das? Wie kann ich das verhindern?

Antwort

9

Beziehungen sind standardmäßig faul. Das bedeutet, dass die SQL-Abfrage zum Laden der Beziehung nur ausgeführt wird, wenn Sie auf die Eigenschaft zugreifen, die die Beziehung enthält.

Das Problem ist, dass wenn Sie auf eine faule Eigenschaft zugreifen, die nie zuvor aufgerufen wurde, mit der Sitzung geschlossen, dann erhalten Sie diesen Fehler. Sie müssen Lösungen:

  • Sie die Sitzung nicht schließen, bis Sie
  • Vor beendet die Session-Zugriff alle faulen Eigenschaften zu schließen, die später verwendet wird.
2

Schließen Sie die Sitzung nicht, bis Sie mit dem Objekt fertig sind.

Dies ist eine der größten Herausforderungen beim Arbeiten mit NHIbernate IMHO: Definieren der Sitzungsgrenzen.

In einer ASP.NET-Anwendung ist es recht einfach: Die Sitzung beginnt am Anfang der Anfrage, und Sie können die Sitzung am Ende der Anfrage schließen.

In einer WinForms-App ist es etwas schwieriger: Sie müssen die Grenzen des Beginns einer Sitzung und des Schließens der Sitzung klar definieren. In WinForms-Anwendungen definiere ich normalerweise "Aufgaben", die eine Art von Arbeitseinheit darstellen. Jede Aufgabe hat eine Sitzung. Die Sitzung wird beim Erstellen einer Aufgabe erstellt/geöffnet und beim Beenden der Aufgabe geschlossen.

Daneben können Sie auch einige Verknüpfungen als nicht faul definieren. Sie sollten jedoch sicherstellen, dass die Leistung nicht beeinträchtigt wird, wenn Sie dies tun.

0

Weiter zu Frederik und Lujop Antworten, wenn Sie an einer ASP.NET-App arbeiten (wie von Ihrer Erwähnung eines Web-Servers vorgeschlagen), ist es eine gute Idee, eine Abhängigkeitsinjektion Framework (wie Castle Windor) zu verwenden Behandeln Sie den Lebenszyklus Ihrer ISessions. Castle Windsor hat eine Lifestyle-Einstellung von "PerWebRequest", die dies für Sie tut.

Wenn dies nicht möglich ist, erstellen Sie manuell eine ISession zu Beginn jeder Anfrage, die am Ende der Anfrage zerstört wird (möglicherweise automatisch selbst entleert wird). Dann kann Ihre App diese ISession verwenden.

Dies ist definitiv mit einer ISession zu tun, die geschlossen wird, bevor Sie denken, dass es ist.

8

Um dieses Problem zu vermeiden, müssen Sie Referenz für PeerGroups in Ihrer Region Mapping-Klasse ändern, wie unter

 
References(x => x.PeerGroupId, "PeerGroupId").Fetch.Join(); 

Hinzufügen Fetch.Join() wird LazyInitializationException verhindern.

+0

Dies ist die tatsächliche Antwort. – Alex

Verwandte Themen