I’ve recently migrated a project off of LINQ-to-SQL and on to NHibernate. So far, I’m really happy with the outcome. NHibernate is infinately more flexible than LINQ-to-SQL and (probably) Entity Framework.

All of my tests were green so I needed to run the smoke tests on my web app. In test, I configured everything via a hibernate.cfg.xml file that lived with the unit test project (MSTest, for those wondering). In production I obviously don’t want to maintain two configuration files so I merged hibernate.cfg.xml from test in to my Web.config.

Configuring with Web.config…easy, right?

Well, not so much. I had some troubles at first: I was using a singleton for configuration, so on first visit the configuration would fail. On subsequent visits the configuration wasn’t reporting failure but the proxies wouldn’t load. I asked Stack Overflow what the deal was to no avail.

It turned out my configuration was incorrect! I was using the wrong type in my <configSections/> bit. Here is what eventually worked for me — if you copypasta this in to your Web.config, I bet it will work for you too.

    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>

  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory name="">
      <property name="connection.provider">
      <property name="connection.driver_class">
      <property name="connection.connection_string">
	    <!-- Insert Connection String Here -->

	  <!-- This is specifically for MSSQL 2008 -->
      <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
      <property name='proxyfactory.factory_class'>
	    NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle

	  <!-- This assembly has a hibernate.hbm.xml file embedded in it. -->
      <mapping assembly="Backplane"/>

	  <!-- These are specific to my project, you don't need these -->
      <listener class="Backplane.Sql.Listeners.SaveEventListener, Backplane" type="save"/>
      <listener class="Backplane.Sql.Listeners.UpdateEventListener, Backplane" type="update"/>

There are a few caveats to be aware of:

  1. Use NHibernate.Cfg.ConfigurationSectionHandler instead of the NameValueConfigurationCollection in your <configSections/>. NameValueConfigurationCollection does not work for me. I saw some references out there to NameValueConfigurationCollection but I don’t think NHibernate 2 supports it, perhaps?
  2. The configuration section name matters! I saw a lot of different configuration section names out there but since we’re using a configuration section handler, the name will matter! “hibernate-configuration” is what worked for me and I think that’s what the documentation points to as well.

Over all, the migration wasn’t painless but with these considerations in mind hopefully it will be easier on the next guy.