gpt4 book ai didi

带有 Rhino 安全性的 NHibernate - 非法尝试将代理与两个打开的 session 相关联

转载 作者:行者123 更新时间:2023-12-03 09:46:25 25 4
gpt4 key购买 nike

我在 ASP.NET MVC 3 应用程序中使用 Rhino Security 作为我在 NHibernate 之上的安全层。当我尝试删除安全实体时,Rhino 安全性会触发 OnPreDelete 方法,用于清理数据库中的相应数据。此时我收到了 非法尝试将代理与两个打开的 session 相关联 错误。

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)

从我对这个主题的阅读来看,这个错误通常是由糟糕的 session 管理引起的,但从源代码看来,Rhino Security 正在使用现有的 session (注意,下面的 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);

我的 session 管理也非常简单,使用 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();
}
}
}

任何人都可以提供有关为什么会出现此问题的指导吗?

提前致谢

最佳答案

我仍然不明白问题的根本原因,但找到了解决方法。以前我的删除方法加载了一个代理,然后执行删除

var entity = session.Load<T>(21415);
session.Delete(entity);

用以下代码替换上面的代码解决了这个问题:
 var queryString = string.Format("delete {0} where id = :id", typeof(T));
Session.CreateQuery(queryString)
.SetParameter("id", id)
.ExecuteUpdate();

显然后者避免了创建代理并执行直接删除

关于带有 Rhino 安全性的 NHibernate - 非法尝试将代理与两个打开的 session 相关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8707585/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com