Leeren Sie die Sitzung nicht, nachdem eine Ausnahme aufgetreten ist - NHibernate

8

Ich entwickle eine ASP.NET MVC Web App unter .NET 3.5, NHibernate und gehostet auf Windows Azure. Wenn die Webanwendung von der lokalen Entwicklungsumgebung ausgeführt wird, funktioniert sie einwandfrei. Wenn ich es jedoch nach Windows Azure verschiebe, endet jede von der MVC-Webrolle durchgeführte Einfügung mit der unten aufgeführten Ausnahme.

Irgendeine Idee, was mit meiner NHibernate Logik falsch ist? (möglicherweise die Sitzungsverwaltung, nicht sicher)

  

[AssertionFailure: Null-ID in Lokad.Translate.Entities.User-Eintrag (die Sitzung nicht löschen, nachdem eine Ausnahme auftritt)]      NHibernate.Event.Default.DefaultFlushEntityEventListener.CheckId (Objektobjekt, IEntityPersister-Persister, Objekt-ID, EntityMode-Entitätsmodus) +292      NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues ​​(Objektidentität, EntityEntry-Eintrag, EntityMode-Entitätsmodus, boolesche moteBeDirty, ISessionImplementor-Sitzung) +93      NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity (FlushEntityEvent-Ereignis) +158      NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities (FlushEvent-Ereignis) +469      NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExuctions (FlushEvent-Ereignis) +339      NHibernate.Event.Default.DefaultFlushEventListener.OnFlush (FlushEvent-Ereignis) +85      NHibernate.Impl.SessionImpl.Flush () +275      NHibernate.Transaction.AdoTransaction.Commit () +236      Lokad.Translate.Repositories.PageRepository.Create (Seitenseite)      Lokad.Translate.Controllers.PagesController.Create (Seite Seite)      lambda_method (ExecutionScope, ControllerBase, Object []) +69      System.Web.Mvc.ReflectedActionDescriptor.Execute (Parameter ControllerContext controllerContext, IDictionary 2 parameters) +251 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2) +31      System.Web.Mvc. & Lt; & gt; c__DisplayClassa.b__7 () +88      System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (IActionFilter-Filter, ActionExecutingContext-PreContext, Func 1 continuation) +534 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList 1-Filter, ActionDescriptor-ActionDescriptor, IDictionary'2-Parameter) +312      System.Web.Mvc.ControllerActionInvoker.InvokeAction (ControllerContext controllerContext, Zeichenfolge actionName) +856      System.Web.Mvc.Controller.ExecuteCore () +185      System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase httpContext) +221      System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +586      System.Web.HttpApplication.ExecuteStep (IExecutionStep-Schritt, Boolean & amp; abgeschlossenSynchron) +177

Beachten Sie, dass ich _session.FlushMode = FlushMode.Commit; verwende und dass User in einer benutzerdefinierten RoleProvider

verwendet wird %Vor%     
Joannes Vermorel 30.11.2009, 10:36
quelle

3 Antworten

4

Ich habe endlich eine Lösung für mein eigenes Problem gefunden. Falls die Leute interessiert sind, schreibe ich die Lösung hier.

%Vor%

Im Grunde ist es so, dass das Repository RoleProvider nicht den gleichen Lebenszyklus aufweist wie normale In-View / In-Controller-Repositories. Daher wurde die NHibernate-Sitzung zum Zeitpunkt des Aufrufs des RoleProvider bereits verworfen, was die oben beschriebene Ausnahme verursachte.

Ich habe den Code oben durch den folgenden Code ersetzt. Dieser hat sein eigenes NHibernate Sitzungsmanagement und funktioniert gut.

    
Joannes Vermorel 30.11.2009, 22:08
quelle
18

Sie sollten niemals Ausnahmen abfangen und sie während einer NHibernate-Transaktion ignorieren.

Ich versuche zu erklären, warum.

Es könnte Ausnahmen geben, die beispielsweise durch Einschränkungen in der Datenbank verursacht werden. (Dies kann auch durch Zuordnungsprobleme verursacht werden, Ausnahmen, die von Eigenschaften ausgelöst werden, oder irgendetwas anderes.) NHibernate versucht, den Status im Speicher mit der Datenbank zu synchronisieren. Dies geschieht beim Commit - und manchmal vor den Abfragen, um sicherzustellen, dass Abfragen auf tatsächlichen Daten ausgeführt werden. Wenn diese Synchronisation fehlschlägt, ist der Status in der Datenbank zufällig. Einige Änderungen werden beibehalten, andere nicht. Das einzige, was Sie in einem solchen Fall tun können, ist das Schließen der Sitzung.

Berücksichtigen Sie, dass Entscheidungen und Berechnungen in Ihrem Code auf Werten im Speicher basieren . Aber - im Falle einer ignorierten Ausnahme sind diese Werte nicht die Werte in der Datenbank, sie werden niemals da sein. Deine Logik wird also entscheiden und auf 'Fantasy-Daten' rechnen.

Übrigens, ist es nie eine gute Idee, eine Ausnahme zu fangen (untypisiert) und sie zu ignorieren . Sie sollten immer wissen, welche Ausnahmen Sie behandeln, und stellen Sie sicher, dass Sie fortfahren können.

Was Sie hier machen, ist das Schlucken von Programmierfehlern. Glauben Sie mir, das System wird nicht stabiler sein. Die Frage ist nur: bemerken Sie den Fehler, wenn es auftritt, oder ignorieren Sie es dort und sogar persistent das Ergebnis des Fehlers in der Datenbank ? Wenn Sie Letzteres tun, müssen Sie nicht überrascht sein, wenn Ihre Datenbank inkonsistent ist und andere Fehler auftreten, wenn Sie versuchen, die Daten aus der Datenbank zu erhalten. Und Sie werden nie den Code finden, der die eigentliche Ursache des Fehlers ist.

    
Stefan Steinegger 30.11.2009 11:03
quelle
0

Diese Ausnahme kann auftreten, wenn Ihre Spaltennamen reservierte Wörter enthalten (z. B. den Status als Spaltennamen verwenden und Speichern nicht möglich ist)

    
increddibelly 12.04.2012 11:59
quelle

Tags und Links