我在 ASP.NET MVC 3 应用程序中使用 Rhino Security 作为 NHibernate 之上的安全层。当我试图删除一个安全实体时,Rhino 安全触发了一个 OnPreDelete 方法,用于清理数据库中的相应数据。此时我收到一个非法尝试将代理与两个打开的会话相关联的错误。
2012-01-02 21:47:52,176 [9] ERROR NHibernate.Event.Default.AbstractFlushingEventListener [(null)] - Could not synchronize database state with session
NHibernate.LazyInitializationException: Initializing[Rhino.Security.Model.EntityType#8007cc24-9cdd-447c-a9cd-9fcc015fa95c]-Illegally attempted to associate a proxy with two open Sessions
at NHibernate.Proxy.AbstractLazyInitializer.set_Session(ISessionImplementor value)
at NHibernate.Engine.StatefulPersistenceContext.ReassociateProxy(ILazyInitializer li, INHibernateProxy proxy)
at NHibernate.Engine.StatefulPersistenceContext.ReassociateIfUninitializedProxy(Object value)
at NHibernate.Event.Default.ProxyVisitor.ProcessEntity(Object value, EntityType entityType)
at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Object value, IType type)
at NHibernate.Event.Default.AbstractVisitor.ProcessValue(Int32 i, Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractVisitor.ProcessEntityPropertyValues(Object[] values, IType[] types)
at NHibernate.Event.Default.AbstractVisitor.Process(Object obj, IEntityPersister persister)
at NHibernate.Event.Default.DefaultDeleteEventListener.OnDelete(DeleteEvent event, ISet transientEntities)
at NHibernate.Event.Default.DefaultDeleteEventListener.OnDelete(DeleteEvent event)
at NHibernate.Impl.SessionImpl.FireDelete(DeleteEvent event)
at NHibernate.Impl.SessionImpl.Delete(Object obj)
at Rhino.Security.DeleteEntityEventListener.OnPreDelete(PreDeleteEvent deleteEvent) in C:\Users\jirwin\Downloads\rhino\rhino-security\Rhino.Security\DeleteEntityEventListener.cs:line 43
at NHibernate.Action.EntityDeleteAction.PreDelete()
at NHibernate.Action.EntityDeleteAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
从我对这个主题的阅读来看,这个错误通常是由错误的会话管理引起的,但是从源代码看来,Rhino Security 正在使用现有的会话(注意,下面的 Delete 方法调用是有问题的方法):
ISession childSession = deleteEvent.Session.GetSession(EntityMode.Poco);
// because default flush mode is auto, a read after a scheduled delete will invoke
// the auto-flush behaviour, causing a constraint violation exception in the
// underlying database, because there still are EntityGroup entities that need
// the deleted EntityReference/SecurityKey.
childSession.FlushMode = FlushMode.Commit;
childSession.Delete(entityReference);
我的会话管理也非常简单,使用 MVC 操作过滤器属性来打开和提交事务,如下所示:
public class NHibernateActionFilter : ActionFilterAttribute
{
private static readonly ISessionFactory sessionFactory = BuildSessionFactory();
private static ISessionFactory BuildSessionFactory()
{
return new Configuration()
.Configure()
.BuildSessionFactory();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var sessionController = filterContext.Controller as SessionController;
if (sessionController == null)
return;
sessionController.Session = sessionFactory.OpenSession();
sessionController.Session.BeginTransaction();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var sessionController = filterContext.Controller as SessionController;
if (sessionController == null)
return;
using (var session = sessionController.Session)
{
if (session == null)
return;
if (!session.Transaction.IsActive)
return;
if (filterContext.Exception != null)
session.Transaction.Rollback();
else
session.Transaction.Commit();
}
}
}
任何人都可以提供有关为什么会发生此问题的指导吗?
提前致谢