views:

772

answers:

2

This is in a web application environment:

An initial request is able to successfully complete, however any additional requests return a "Session is Closed" response from the NHibernate framework. I'm using a HttpModule approach with the following code:

public class MyHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += ApplicationEndRequest;
        context.BeginRequest += ApplicationBeginRequest;
    }

    public void ApplicationBeginRequest(object sender, EventArgs e)
    {
        CurrentSessionContext.Bind(SessionFactory.Instance.OpenSession());
    }

    public void ApplicationEndRequest(object sender, EventArgs e)
    {
        ISession currentSession = CurrentSessionContext.Unbind(
            SessionFactory.Instance);

        currentSession.Dispose();
    }

    public void Dispose() { }
}

SessionFactory.Instance is my singleton implementation, using FluentNHibernate to return an ISessionFactory object.

In my repository class, I attempt to use the following syntax:

public class MyObjectRepository : IMyObjectRepository
{
    public MyObject GetByID(int id)
    {
        using (ISession session = SessionFactory.Instance.GetCurrentSession())
            return session.Get<MyObject>(id);
    }
}

This allows code in the application to be called as such:

IMyObjectRepository repo = new MyObjectRepository();
MyObject obj = repo.GetByID(1);

I have a suspicion my repository code is to blame, but I'm not 100% sure on the actual implementation I should be using.

I found a similar issue on SO here. I too am using WebSessionContext in my implementation, however, no solution was provided other than writing a custom SessionManager. For simple CRUD operations, is a custom session provider required apart from the built in tools(ie WebSessionContext)?

+2  A: 

I haven't tested your code, but from reading, this line:

using (ISession session = SessionFactory.Instance.GetCurrentSession())

is dumping your session after the block exits, and then the session is disposed/invalid on the next time through.

Here's the model we're using in our applications:

ISession session = null;

try
{
    // Creates a new session, or reconnects a disconnected session
    session = AcquireCurrentSession();

    // Database operations go here
}
catch
{
    session.Close();
    throw;
}
finally
{
    session.Disconnect();
}
Jon Seigel
A: 

Try using the IUnityContainer.Resolve() method instead of "new"ing up your MyObjectRepository.