The new statistics class in Hibernate 2.0 is a great tool to use for monitoring potential performance problems with your app. The class exposes a large number of counters and measurements. Here are some highlights of what is available:

  • EntityDeleteCount
  • EntityInsertCount
  • EntityLoadCount
  • EntityUpdateCount
  • QueryExecutionCount
  • QueryExecutionMaxTime
  • QueryExecutionMaxTimeQueryString
  • QueryCacheHitCount
  • ConnectCount
  • SessionCloseCount
  • SessionOpenCount
  • CollectionLoadCount
  • CollectionUpdateCount
  • CollectionRemoveCount
  • Queries
  • PrepareStatementCount

The statistics engine can be turned on/off dynamically with the IsStatisticsEnabled property and you can get statistics on specific entities as well.

Just to try this out I created a MonoRail filter that checks for "nhibstats" in the query parameters of the request. If the parameter is found it will turn on the nhibernate statistics, this is done before the controller action is executed. After the action as completed it will add the stats data to the PropertyBag so the view can access it.

public class NHibernateStatsFilter : IFilter
{
    public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller,
                        IControllerContext controllerContext)
    {
        if (context.Request["nhibstats"] == null)
            return; 
        
        if (exec == ExecuteWhen.BeforeAction)
        {
            sessionFactory.Statistics.Clear();
            sessionFactory.Statistics.IsStatisticsEnabled = true;
        }
        else if (exec == ExecuteWhen.AfterAction)
        {
            controllerContext.PropertyBag["nhibernate_stats"] = sessionFactory.Statistics;
            sessionFactory.Statistics.IsStatisticsEnabled = false;
        }
    }
}

I use the same filter for both the before and after action "events", this means that you have to specify the filter attribute like this:
[Filter(ExecuteWhen.BeforeAction | ExecuteWhen.AfterAction, typeof(NHibernateStatsFilter))]
public class BaseController : Controller
{
        
}
Now you can add to your top layout view something like this:
<?brail if IsDefined("nhibernate_stats"): ?>
    <dl>
        <dt>EntityInsertCount</dt>
        <dd>${nhibernate_stats.EntityInsertCount}</dd>        
        <dt>EntityUpdateCount</dt>
        <dd>${nhibernate_stats.EntityUpdateCount}</dd>        
        .
        ..
        ...
    </dl>
<?brail end ?>

I think this could be really useful. Now you don't have to open SQL Profiler whenever you want to know what NHibernate is up to!

5 comments:

Anonymous said...

Where do you get your sessionFactory from?

Torkel Ödegaard said...

The example is not complete, in the real complete code I get the sessionfactory from the http module that creates and manages the nhibernate sessions

Tanuka said...

Nice stuff on NHibernate.

ASP.Net MVC Training
Online MVC Training
MVC Training in Chennai
.Net Training in Chennai

Anu Sri said...

Excellent post ! Keep sharing such a informative post.

web designing institute in chennai

Arjun Rishi said...

Great article. Glad to find your blog. Thanks for sharing.

web designing training in chennai