NHibernate / MVC lazy loading with "session closed or no session"

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()
    {
        // Do nothing
    }
}

My SessionFactory is also pretty standard:

public static class SessionFactory
{
    private static ISessionFactory _sessionFactory;

    private static void Init()
    {
        _sessionFactory = Fluently.Configure() //Lots of other stuff here for NH config
            .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);

        // I put this in here as a test -- it throws the no-session error, too.            
        var count = user.Comments.Count();

        var comment = new Comment();
        comment.CommentText = model.CommentText;
        comment.DateCreated = DateTime.UtcNow;
        comment.CreatedBy = UserContext.Current.ActiveUser;

        // This is the original source of the error
        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) //Infrastructure.Querying.Query query)
{
    return detachedCriteria.GetExecutableCriteria(SessionFactory.GetCurrentSession()).Future<T>();
}

, , , , , , . , , - , foreach . .

, - AJAX, , .

, .

+3
3

, . , -, , , , , , - .

, :

var user = svc.FindBy(model.UserId.Value, UserContext.Current.ActiveUser);

UserContext Current, , , NHibernate . - , NHibernate , UserContext.ActiveUser - , :

if (!SessionFactory.GetCurrentSession().Contains(ActiveUser))
    SessionFactory.GetCurrentSession().Refresh(ActiveUser);

- . UserContext, .

, , , . , , !

+1

, . , , ?

"--" "--" "".

"" session.Lock(..)?

, , .

0

, - .

0

All Articles