Session is closed. Object Name: "ISession". in NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed () - How to stop a session from closing prematurely

I am using NHibernate in a MVC C # application with MySQL. I am trying to have multiple users access a session. I used .InRequestScope() in my session, but I still get:

System.ObjectDisposedException: session closed! Object Name: "ISession". in NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed () *

... or DataReader, when I have my colleagues, go to the same page that accesses the service at the same time.

My injection is IMasterSessionSource

 Bind<IMasterSessionSource>().To<GeneralMasterSessionSource() .InRequestScope(); 

My IContentService is where my mappings get service

  //ContentService Bingings Bind<IContentService>().To<ContentService>().InRequestScope(); Bind<ISession>() .ToMethod( context => context.Kernel.Get<IMasterSessionSource>() .ExposeConfiguration() .BuildSessionFactory() .OpenSession() ) .WhenInjectedInto<IContentService>() .InRequestScope(); 

Content service

 public interface IContentService { IQueryable<Question> Questions{ get; } } public class ContentService : IContentService { private readonly ISession _session; public ContentService(ISession session) { _session = session; } public IQueryable<Question> Questions { get { return _session.Query<Question>(); } } } 

DetailsService

  public interface IDetailsService { IEnumerable<Question> PullQuestions(); } public class DetailsService : IDetailsService { private readonly IContentService _contentService; public GeneralService(IContentService contentService) { _contentService = contentService; } public IEnumerable<Question> PullQuestions() { var result = _contentService.Questions; return result; } } 

CONTROLLER

 public class Test: Controller { private readonly IContentService _contentService; private readonly IGeneralService _generalService; public CollegeController(IContentService contentService, IDetailsService detailsService) { _contentService = contentService; _detailsService = detailsService; } public ActionResult Index() { { var model = new HomePageContent { Questions = _detailsService.PullQuestions().ToList(); }; } } } 

MODEL

  public class HomePageContent { public IEnumerable<Question> Questions { get; set; } } 

VIEW

 foreach(var question in Model.Questions){ @Html.Raw(question.Question) } 

So, for one user visiting this page. Everything is working fine. But when mutliple users view the same page, everyone gets errors:

{"There is already an open DataReader associated with this connection that should be closed first."} {"There is already an open DataReader that should be closed first".} {"There is no current request in the data reader"} {" There is no current request in the data reader "} {" An open DataReader has already been opened to this connection, which should be closed first. "} {" Session is closed! \ R \ nObject: "ISession". "

I already added InRequestScope. I even added this implementation: NHibernate, and the odd session is closed! "Errors

but i still get the sessions closed! mistakes. I even tried to create a new Kernel.Get if the session was closed, but the problem is that the error sometimes occurs even when the session is open. Please help! I end up with this question, and I cannot find a solution anywhere. I almost believe that NHibernate cannot handle multiple sessions at the same time.

UPDATE

Maybe there is a way to wait for a remote session before opening a new one?

Stack trace

[ObjectDisposedException: session closed! Object Name: "ISession".] NHibernate.Impl.AbstractSessionImpl.ErrorIfClosed () +192
NHibernate.Impl.AbstractSessionImpl.CheckAndUpdateSessionStatus () +55 NHibernate.Impl.AbstractSessionImpl.CreateQuery (IQueryExpression queryExpression) +171
NHibernate.Linq.DefaultQueryProvider.PrepareQuery (Expression expression, IQuery & query, NhLinqExpression & nhQuery) +226
NHibernate.Linq.DefaultQueryProvider.Execute (expression expression) +80 NHibernate.Linq.DefaultQueryProvider.Execute (expression expression) +74 Remotion.Linq.QueryableBase 1.GetEnumerator() +193 System.Collections.Generic.List 1..ctor ( IEnumerable 1 collection) +432 System.Linq.Enumerable.ToList(IEnumerable 1 source) +70
Gcus.PublicGeneralSite.Data.Core.Service.General.DetailsService.FindItems (String item, String controller) in C: \ Users \ WD \ Desktop \ Wizard \ Gcus.PublicGeneralSite.Data.Core \ Service \ General \ DetailsService.cs: 724 Gcus.Com.Web.Controllers.CoursesController.Details (String category, String element) in C: \ Users \ WD \ Desktop \ Wizard \ Gcus.Com.Web \ Controllers \ CoursesController.cs: 213 lambda_method (Closure, ControllerBase, Object []) +366
System.Web.Mvc.ActionMethodDispatcher.Execute (ControllerBase controller, object []) +87
System.Web.Mvc.ReflectedActionDescriptor.Execute (ControllerContext controllerContext, IDictionary 2 parameters) +603
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters) +603
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters) +603
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 parameters) +93
System.Web.Mvc.Async.ActionInvocation.InvokeSynchronousActionMethod () +97 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39 (IAsyncResult asyncResult, ActionInvocation innerInvokeState) +53
System.Web.Mvc.Async.WrappedAsyncResult 2.CallEndDelegate(IAsyncResult asyncResult) +137
System.Web.Mvc.Async.WrappedAsyncResultBase
2.CallEndDelegate(IAsyncResult asyncResult) +137
System.Web.Mvc.Async.WrappedAsyncResultBase
2.CallEndDelegate(IAsyncResult asyncResult) +137
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +187
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object tag) +136
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod (IAsyncResult asyncResult) +76
System.Web.Mvc.Async.AsyncInvocationWithFilters.b__3d () +164 System.Web.Mvc.Async. <> c__DisplayClass46.b__3f () +549 System.Web.Mvc.Async. <> c__DisplayClass33.b__32 (IAsyncResult asyncResult) +75
System.Web.Mvc.Async.WrappedAsyncResult 1.CallEndDelegate(IAsyncResult asyncResult) +79
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +79
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +79
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +187
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object tag) +136
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters (IAsyncResult asyncResult) +76
System.Web.Mvc.Async <. > C__DisplayClass2b.b__1c () +114 System.Web.Mvc.Async. <> c__DisplayClass21.b__1e (IAsyncResult asyncResult) +306
System.Web.Mvc.Async.WrappedAsyncResult 1.CallEndDelegate(IAsyncResult asyncResult) +75
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +75
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +75
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +176
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object Tag) +72
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction (IAsyncResult asyncResult) +60
System.Web.Mvc.Controller.b__1d (IAsyncResult asyncResult, ExecuteCoreState innerState) +70
System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +176
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object Tag) +72
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object tag) +51
System.Web.Mvc.Controller.EndExecuteCore (IAsyncResult asyncResult) +66 System.Web.Mvc.Controller.b__15 (IAsyncResult asyncResult, controller controller) +60
System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +98
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +98
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +98
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +176
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object Tag) +72
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object tag) +51 System.Web.Mvc.Controller.EndExecute (IAsyncResult asyncResult) +60
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute (IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.b__5 (IAsyncResult asyncResult, ProcessRequestState innerState) +70
System.Web.Mvc.Async.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.CallEndDelegate(IAsyncResult asyncResult) +135
System.Web.Mvc.Async.WrappedAsyncResultBase
1.End () +176
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object Tag) +72
System.Web.Mvc.Async.AsyncResultWrapper.End (IAsyncResult asyncResult, Object tag) +51
System.Web.Mvc.MvcHandler.EndProcessRequest (IAsyncResult asyncResult) +60 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest (IAsyncResult result) +59
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +399 System.Web.HttpApplication.ExecuteStep (step IExecutionStep, Boolean & completed synchronously) +137

+5
source share
2 answers

I finally figured it out. Many thanks to @Oskar Berggren for at least longing for an understanding of my dilemma.

The problem was that I actually shared one session.

this is where I bind the open session to the ContentService:

  Bind<IContentService>().To<ContentService>().InRequestScope(); Bind<ISession>() .ToMethod( context => context.Kernel.Get<IMasterSessionSource>() .ExposeConfiguration() .BuildSessionFactory() .OpenSession() ) .WhenInjectedInto<IContentService>() .InRequestScope(); 

Here I call the same session in the ContentService

  public class ContentService : IContentService { private readonly ISession _session; public ContentService(ISession session) { _session = session; } public IQueryable<Question> Questions { get { return _session.Query<Question>(); } } } 

That is where the problem is. I am calling a SAME session in another service that is being used elsewhere

 public class DetailsService : IDetailsService { private readonly IContentService _contentService; //BAD public GeneralService(IContentService contentService) { _contentService = contentService; //BAD } 

This is not thread safe because this open session is reused. Each service should have its own session.

so I created a binding for DetailService with my own session like this ....

  Bind<IDetailsService>() .To<DetailsService>() .InRequestScope(); Bind<ISession>() .ToMethod( context => { var lockObject = new object(); lock (lockObject) { return context.Kernel.Get<IMasterSessionSource>() .ExposeConfiguration() .BuildSessionFactory() .OpenSession(); } } ) .WhenInjectedInto<IDetailsService>() .InRequestScope(); 

And instead of calling _contentService in this service, I added a session to its constrictor

  private readonly ISession Session; public DetailsService(ISession session) { Session = session; } 

and then just runs the queries directly using Session.Query ();

no more closed errors session, no more DataReader errors and, finally, a working product.

+1
source

I am not familiar with ninject, who I suspect is involved in the problem here.

If you cannot figure out how to handle sessions correctly, you can take a look at NHibernate's own handling of contextual sessions: http://nhibernate.info/doc/nhibernate-reference/architecture.html#architecture-current-session

0
source

All Articles