Recently there has been some work on the connection model used by NHibernate. Specifically, this work was done to ensure that NHibernate will only hold an open connection for the shortest possible time needed.
Some backgroud first:
This change was driven by an attempt to port the Hibernate Swing demo app, and realizing that NHibernate and Hibernate 3.0 has different connection models. The Hibernate 3.0 connection model was driven by the need to release a connection on method boundaries, because some EJB containers are tracking resources, and would error in cases like this one:
public void ApplyRules(int id)
{
using(ISession session = OpenSession()); // get the session, but the connection is not opened yet.
{
ICollection<Rule> rules = GetRules(session);
session.Load<Employee>(id).Apply(rules);
} // the connection is closed here
}
public ICollection<Rule> GetRules(ISession session)
{
//business logic for finding the correct rules here.
// the connection is opened here
return session.CreateCriteria(typeof(Rule).List<Rule>();
}
In this case, as far as the container care, GetRules has opened a database connection and never closed it, leading to a resource leak. So, Hibernate will close the connection as soon as it can, in this case, the connection is opened in GetRules and then closed, and opened again and closed in ApplyRules. (Performance in this case is not relevant, because we are taking advantage of connection pooling.)
Now, what does it means for web applications:
It is a best practice to keep the lifetime of open DB connections as short as possible, since this frees more resources for concurrent work, so I would bet that this should lead to NHibernate taking less resources than before in most cases.
It is now easier to just take the NHibernate session and put it in the ASP.Net session (although I would still not recommend it for most cases). Session per Conversation pattern has just became slightly easier.
But Windows applications gets the real benefit. The main problem with writing windows applications that uses the database directly was always handling the state of the connection, since you don't want to keep the connection opened for a long period of time, yet you need the connection open to support lazy loading. There are ways to get around that, such as the DataAccessCommand pattern, but they are a bit cumbersome, and not as natural as you could wish.
What we have now is an opened session that will make sure that the connection is only opened when it is needed (freeing us from worrying about it) and give us the natural syntax of just using the objects, with full support for lazy loading.
What it breaks?
Well, it turns out that there is a set of scenarios that this change break. Specifically, all scenarios where the database is only kept alive for the duration of the connection. I have run into this when my tests using in-memory SQLite database started to fail, because the database is being deleted when the connection is closed. A workaround to this is to pass the database connection explicitly to NHibernate, in which case it is assuming that it is your responsability to close the connection, and never closes it.
Again, this is an update from straight from the trunk, it is not released yet.