2009-11-30 57 views
8

我正在.NET 3.5,NHibernate下開發一個ASP.NET MVC Web應用程序,並託管在Windows Azure上。什麼時候,webapp是從本地開發結構運行的,它工作正常。但是,當我將它移動到Windows Azure時,從MVC Web角色執行的每個插入都會以下面列出的例外結束。在發生異常之後不要刷新會話 - NHibernate

任何想法我的NHibernate邏輯有什麼問題? (可能是會話管理,不知道)

[AssertionFailure:在Lokad.Translate.Entities.User進入空ID(發生異常後不要衝洗會議)] NHibernate.Event.Default。 DefaultFlushEntityEventListener.CheckId(obj對象,IEntityPersister留存,對象ID,EntityMode entityMode)+292 NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues(對象實體,EntityEntry項,EntityMode entityMode,布爾mightBeDirty,ISessionImplementor會話)+93 NHibernate.Event .Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event)+158 NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event)+469 NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent事件)339 NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent事件)85 NHibernate.Impl.SessionImpl.Flush()275 NHibernate.Transaction.AdoTransaction .Commit()236 Lokad.Translate.Repositories.PageRepository.Create(頁頁) Lokad.Translate.Controllers.PagesController.Create(頁頁) lambda_method(ExecutionScope,ControllerBase,對象[])69 系統。 Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary 2 parameters) +251 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2 parameters)+31 System.Web.Mvc。 <> c__DisplayClassa.b__7()88 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter濾波器,ActionExecutingContext preContext,函數功能1 continuation) +534 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList 1個濾波器,ActionDescriptor actionDescriptor,IDictionary`2參數)312 System.Web.Mvc.ControllerActionInvoker。 InvokeAction(ControllerContext controllerContext,String 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 step,布爾型& completedSynchronously已完成)+177

請注意,我用的_session.FlushMode = FlushMode.Commit;,而且User在自定義RoleProvider

public class SimpleRoleProvider : RoleProvider 
{ 
    readonly UserRepository Users = new UserRepository(); 

    public override string[] GetRolesForUser(string username) 
    { 
     try 
     { 
      var user = Users.Get(username); 

      // no role if user is not registered 
      if (null == user) return new string[0]; 

      // default role for registered user 
      return user.IsManager ? new[] { "Manager", "User" } : new[] { "User" }; 
     } 
     catch (Exception) 
     { 
      // role should not fail in case of DB issue. 
      return new string[0]; 
     } 
    } 
} 

回答

4

我終於找到了解決我自己的問題。如果人們有興趣,我在這裏發佈解決方案。

public class SimpleRoleProvider : RoleProvider 
{ 
    // isolated session management for the RoleProvider to avoid 
    // issues with automated management of session lifecycle. 

    public override string[] GetRolesForUser(string username) 
    { 
     using (var session = GlobalSetup.SessionFactory.OpenSession()) 
     { 
      var users = new UserRepository(session); 
      var user = users.Get(username); 

      // no role if user is not registered 
      if (null == user) return new string[0]; 

      // default role for registered user 
      return user.IsManager ? new[] {"Manager", "User"} : new[] {"User"}; 
     } 
    } 
} 

基本上發生了什麼事情是,RoleProvider庫似乎並不具有比普通的視/在控制器庫相同的生命週期。因此,在調用RoleProvider時,NHibernate會話已經被處置,導致上面觀察到的異常。

我已經用上面的代碼替換了下面的代碼。這個有它自己的NHibernate會話管理,並且最終工作正常。可發生

18

使用你不應該捕捉異常和NHibernate的交易過程中忽略它們。

我試圖解釋爲什麼。

由於數據庫中的約束可能存在例外情況。 (它也可能是由映射問題,屬性拋出的異常或其他引起的。)NHibernate嘗試將內存中的狀態與數據庫同步。這是在提交時完成的 - 有時在查詢之前確保查詢是在實際數據上完成的。當這個同步失敗時,數據庫中的狀態是隨機的,有些變化是持久的,有些則不變。在這種情況下你唯一能做的就是關閉會話。

請考慮您的代碼中的決策和計算是基於內存中的值。但是 - 如果有一個被忽略的異常,這個值不是數據庫中的值,它們將永遠不會在那裏。所以你的邏輯將決定和計算'幻想數據'。

順便說一句,從來不是一個好主意,以捕獲任何異常(無類型),並忽略它們。您應該始終知道您處理的例外情況,並確保您可以繼續。

你在這裏做的是吞嚥編程錯誤。相信我,系統不會更穩定。問題只是:你是否注意到錯誤發生時,或者你忽略它,甚至將錯誤的結果持續到數據庫?當您執行後者時,當您嘗試從數據庫獲取數據時,數據庫不一致時出現其他錯誤時不必感到驚訝。而且你將永遠無法找到導致錯誤真正原因的代碼。

+0

嗨斯蒂芬,非常感謝您的詳細解釋。我終於找到了一個解決方案。問題與你的解釋無關,但它仍然是一個很好的觀點。 – 2009-11-30 22:01:36

+0

非常感謝你的詳細解釋我有同樣的錯誤,它是由吞噬NHibernate異常造成的。我通過閱讀您的文章節省了大量時間。 – Vladimirs 2013-05-01 15:14:20

0

此異常,如果你的列名包括保留字(例如,作爲列名使用狀態,它會變得無法保存)