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.

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

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

	  <!-- 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
	  </property>

	  <!-- 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"/>
    </session-factory>
  </hibernate-configuration>
</configuration>

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.

About these ads