I use Rhino Security as my security level on top of NHibernate in an ASP.NET MVC 3 application. When I try to delete a protected object, the Rhino system disables the OnPreDelete method used to clear the corresponding data in the database. At this point, I get an Unlawful attempt to associate a proxy with two open sessions .
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)
From my reading on the topic, this error is usually caused by improper session management, but from the source code it seems that Rhino Security is using an existing session (note that the Delete method method below is a violation 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);
Session management is also quite simple using the MVC action filter attribute to open and commit transactions as follows:
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(); } } }
Can someone give guidance as to why this problem occurs?
Thank you in advance
source share