I use NHibernate behind my ASP.NET MVC application, and I encountered a frustrating problem when trying to save an object through an AJAX call. I get the usual one:
Failed to lazily initialize the role collection: [type] no session or session was closed
The problem is, as far as I can tell, the session is not closed. I am using an HttpModule to process my sessions in a session for a query template with NHibernate to use web current_session_context_class. Here's the HttpModule:
public class NHHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.EndRequest += ApplicationEndRequest;
context.BeginRequest += ApplicationBeginRequest;
}
public void ApplicationBeginRequest(object sender, EventArgs e)
{
CurrentSessionContext.Bind(SessionFactory.GetNewSession());
}
public void ApplicationEndRequest(object sender, EventArgs e)
{
var currentSession = CurrentSessionContext.Unbind(SessionFactory.GetSessionFactory());
currentSession.Close();
currentSession.Dispose();
}
public void Dispose()
{
}
}
My SessionFactory is also pretty standard:
public static class SessionFactory
{
private static ISessionFactory _sessionFactory;
private static void Init()
{
_sessionFactory = Fluently.Configure()
.BuildSessionFactory();
}
public static ISessionFactory GetSessionFactory()
{
if (_sessionFactory == null)
Init();
return _sessionFactory;
}
public static ISession GetNewSession()
{
return GetSessionFactory().OpenSession();
}
public static ISession GetCurrentSession()
{
return GetSessionFactory().GetCurrentSession();
}
}
I use a unit of work for transactions, so I do not open a transaction in BeginRequest. However, I tried this without any change in the results.
Comment User AJAX. :
[HttpPost, ValidateInput(false)]
public ActionResult CreateCommentAsync(CommentCreateViewModel model)
{
if (!model.UserId.HasValue)
return Content("false");
var svc = DependencyResolver.Current.GetService<IPartnerUserService>();
var user = svc.FindBy(model.UserId.Value, UserContext.Current.ActiveUser);
var count = user.Comments.Count();
var comment = new Comment();
comment.CommentText = model.CommentText;
comment.DateCreated = DateTime.UtcNow;
comment.CreatedBy = UserContext.Current.ActiveUser;
user.Comments.Add(comment);
svc.Save(user, UserContext.Current.ActiveUser);
return Content("true");
}
, , , , SessionFactory.GetCurrentSession().IsOpen , .
, Comments , . , , .
, , , . ... ? , , , , , , , . ?
UPDATE:
, , , . . :
if (!SessionFactory.GetCurrentSession().Contains(user))
SessionFactory.GetCurrentSession().Refresh(user);
true .
, , , , . , :
public IEnumerable<T> FindBy(DetachedCriteria detachedCriteria)
{
return detachedCriteria.GetExecutableCriteria(SessionFactory.GetCurrentSession()).Future<T>();
}
, , , , , , . , , - , foreach . .
, - AJAX, , .
, .