NHibernate and Rhino Security – illegally trying to associate a proxy with two open sessions

I am using Rhino Security as my security layer on top of NHibernate in my ASP.NET MVC 3 application. When I try to delete a secure entity, Rhino Security triggers for cleanup The OnPreDelete method of the corresponding data in the database. At this time, I received an illegal attempt to associate the proxy with two open Sessions errors.

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(ILliazyInitial , INHibernateProxy proxy)
at NHibernate.Engine.StatefulPersistenceContext.ReassociateIfUninitializedProxy(Object value)
at NHibernate.Event.Default.ProxyVisitor.ProcessEntity(Object value, EntityType entityType)
at NHibernate.Event. Default.AbstractVisitor.P rocessValue(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)

From my reading of the topic, this error is usually caused by incorrect session management, but from the source code, Rhino Security An existing session is being used (note that the Delete method call below is the offending method):

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);

My session management also Very simple, use the MVC action filter attribute to open and commit the transaction, as shown below:

public class NHibernateActionFilter : ActionFilterAttribute
{
private static readonly ISessionFactory sessionFactory = BuildSessionFactory();

private static ISessionFactory BuildSessionFactory()
{
return new Configuration()< br /> .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;
< br /> if (sessionController == null)
return;

using (var session = sessionController.Session)
{
if (session == null)
return;

if (!session.Transaction.IsActive) < br /> return;

if (filterContext.Exception != null)
session.Transaction.Rollback();
else
session.Transaction.Commit() ;
}
}
}

Can anyone provide guidance on why this problem occurs?

Thanks in advance

I still don’t understand the root cause of the problem, but I found The solution. Previously, my delete method loaded an agent, and then executed delete

var entity = session.Load(21415);
session.Delete(entity);

Replace the above code with the following code to solve this problem:

var queryString = string.Format("delete {0} where id = :id", typeof(T));
Session.CreateQuery(queryString)
.SetParameter("id", id)
.ExecuteUpdate();

Obviously, the latter avoids the creation of the proxy and performs direct deletion

I use Rhino Security as my security in my ASP.NET MVC 3 application The layer is on top of NHibernate. When I try to delete a secure entity, Rhino security triggers the OnPreDelete method to clean up the corresponding data in the database. At this point, I receive an illegal attempt to associate the proxy with two open Sessions errors .

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 associa te a proxy with two open Sessions
at NHibernate.Proxy.AbstractLazyInitializer.set_Session(ISessionImplementor value)
at NHibernate.Engine.StatefulPersistenceContext.ReassociateProxy(ILazyInitializer li, INHibernateProxy proxy)
Engine at NHibernate. .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.Def ault.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)

From my reading of the topic, this error is usually managed by the wrong session Caused, but from the source code, Rhino Security is using an existing session (note that the following Delete method call is an illegal method):

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);

My session management is also very simple ,Use the MVC operation filter attribute to open and submit the transaction, as shown below:

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;< br />
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;< br />
if (!session.Transaction.IsActive)
return;

if (filterContext.Exception != null)
session.Transaction.Rollback() ;
else
session.Transaction.Commit();
}
}
}

Can anyone provide information on why this problem occurred The guidance?

Thanks in advance

I still don’t understand the root cause of the problem, but I found a solution. Previously, my delete method loaded a Proxy, and then execute delete

var entity = session.Load(21415);
session.Delete(entity);

Replace the above code with the following code to solve this problem:

var queryString = string.Format("delete {0} where id = :id", typeof( T));
Session.CreateQuery(queryString)
.SetParameter("id", id)
.ExecuteUpdate();

Obviously, the latter avoids the proxy Create and execute direct deletion

Leave a Comment

Your email address will not be published.