I’m writing a web app using ASP.NET MVC 2 and picked NHibernate as my ORM. I basically learned my basics from watching the Summer of NHibernate series, and have adopted the authors session per request strategy for managing a session (Ep 13). Things seem to work well, but I’m concerned about whether this is a functional real world approach to managing a session and being thread safe. If not then I’m open to other examples.
I’ve added code to elaborate.
Here is my code that sets up the SessionFactory:
public class NHibernateSessionManager
{
public static readonly ISessionFactory SessionFactory;
static NHibernateSessionManager()
{
try
{
Configuration cfg = new Configuration();
if (SessionFactory != null)
throw new Exception("trying to init SessionFactory twice!");
SessionFactory = cfg.Configure().BuildSessionFactory();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
throw new Exception("NHibernate initialization failed", ex);
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
And this is where I have the web request start and stop the transaction:
public class NHibernateSessionPerRequestModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest +=new EventHandler(Application_BeginRequest);
context.EndRequest +=new EventHandler(Application_EndRequest);
}
private void Application_BeginRequest(object sender, EventArgs e)
{
ISession session = NHibernateSessionManager.OpenSession();
session.BeginTransaction();
CurrentSessionContext.Bind(session);
}
private void Application_EndRequest(object sender, EventArgs e)
{
ISession session = CurrentSessionContext.Unbind(NHibernateSessionManager.SessionFactory);
if(session != null)
try
{
session.Transaction.Commit();
}
catch (Exception)
{
session.Transaction.Rollback();
}
finally
{
session.Close();
}
}
}
And this is how I would grab a session from the session factory for one of my repositories in a Controller class:
CompanyRepository _companyRepository = new CompanyRepository(NHibernateSessionManager.SessionFactory.GetCurrentSession());
I was curious so I googled around.
HttpContext.Items can be used by multiple threads.
Nhibernate Sessions are not thread safe.
And then there is there answer: ( possible dupe )
NHibernate thread safety with session
So it seems this recipe for disaster can be managed effectively. Because you didn’t post the code that Summer of Nhibernate uses its hard to say whether your implementation won’t fall over.