Я использую Rhino Security в качестве уровня безопасности поверх NHibernate в приложении ASP.NET MVC 3. Когда я пытаюсь удалить защищенный объект, Rhino security запускает метод 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();
}
}
}
Может ли кто-нибудь дать руководство относительно того, почему возникает эта проблема?
Заранее спасибо