知道我的NHibernate逻辑有什么问题吗? (可能是会话管理,不确定)
[AssertionFailure: null id in Lokad.Translate.Entities.User entry (don’t flush the Session after an exception occurs)]
NHibernate.Event.Default.DefaultFlushEntityEventListener.CheckId(Object obj,IEntityPersister persister,Object id,EntityMode entityMode) +292
NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues(Object entity,EntityEntry entry,EntityMode entityMode,Boolean mightBeDirty,ISessionImplementor session) +93
NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event) +158
NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event) +469
NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +339
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +85
NHibernate.Impl.SessionImpl.Flush() +275
NHibernate.Transaction.AdoTransaction.Commit() +236
Lokad.Translate.Repositories.PageRepository.Create(Page page)
Lokad.Translate.Controllers.PagesController.Create(Page page)
lambda_method(ExecutionScope,ControllerBase,Object[] ) +69
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary2 parameters) +251
2 parameters) +31
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary
System.Web.Mvc.<>c__DisplayClassa.b__7() +88
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter,ActionExecutingContext preContext,Func1 continuation) +534
1 filters,IDictionary`2 parameters) +312
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext,IList
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,Boolean& completedSynchronously) +177
请注意,我使用的是_session.FlushMode = FlushMode.Commit;并且用户在自定义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]; } } }
解决方法
我试着解释原因.
例如,可能存在由数据库中的约束引起的异常. (它也可能是由映射问题,属性或其他任何东西引发的异常引起的.)NHibernate尝试将内存中的状态与数据库同步.这是在提交时完成的 – 有时在查询之前完成,以确保对实际数据进行查询.当此同步失败时,数据库中的状态是随机的,某些更改会保留,而其他更改则不会.在这种情况下,你唯一能做的就是关闭会话.
请考虑代码中的决策和计算基于内存中的值.但是 – 如果忽略异常,这个值不是数据库中的值,它们永远不会存在.因此,您的逻辑将决定并计算“幻想数据”.
顺便说一句,捕获任何异常(无类型)并忽略它们永远不是一个好主意.您应该始终知道您处理的例外情况,并确保可以继续.
你在这里做的是吞咽编程错误.相信我,系统将不会更稳定.问题只是:你是否注意到它发生时的错误,或者你是否忽略它,甚至将错误的结果保存到数据库中?当你执行后者时,当数据库不一致时,你不必感到惊讶,当你试图从数据库中获取数据时会出现其他错误.而且你永远不会找到导致错误的实际原因的代码.