In this question I asked about NHibernate session lifetime. I'm using a desktop application, but with client/server separation, so the conclusion is that I will use one session per server request, as the server side is where all the NHibernate magic happens.
My problem now is how to handle it. I've had problems before with loading of referenced data when the session is prematurely closed. The problem is that I see the following on my referenced classes when debugging - hence the referenced data isn't loaded yet:
base {NHibernate.HibernateException} = {"Initializing[MyNamespace.Foo#14]-failed to lazily initialize a collection of role: MyNamespace.Foo.Bars, no session or session was closed"}
From what I understand it doesn't load all even though I commit the transaction. So I've learned that I need to keep my session open for a while, but how long?
My question is basically if I'm handling the lifetime properly, or what I should change to be on the right track. Honestly I can't see how this can be wrong, so what I'd really like is a function call to ensure that the referenced data is fetched. I'm not using lazy loading, so I thought they would be loaded immediately..?
Current architecture: Using a "service behavior" class that does the transaction. This is IDisposable, so the service itself it using a using-clause around it. The NHibernateSessionFactory provides a static factory which hence will be resused.
// This is the service - the function called "directly" through my WCF service.
public IList<Foo> SearchForFoo(string searchString)
{
using (var serviceBehavior = new FooServiceBehavior(new NhibernateSessionFactory()))
{
return serviceBehavior.SearchForFoo(searchString);
}
}
public class FooServiceBehavior : IDisposable
{
private readonly ISession _session;
public FooServiceBehavior(INhibernateSessionFactory sessionFactory)
{
_session = sessionFactory.OpenSession();
}
public void Dispose()
{
_session.Dispose();
}
public IList<Foo> SearchForFoo(string searchString)
{
using (var tx = _session.BeginTransaction())
{
var result = _session.CreateQuery("from Foo where Name=:name").SetString("name", searchString).List<Name>();
tx.Commit();
return result;
}
}