views:

359

answers:

2

So my unit tests are green, time to integrate this shiny new NHibernate-driven DAL in to my web app! I don't really want to maintain two configuration files so I've migrated hibernate.cfg.xml in to my Web.config file (i.e. I copypasta'd the contents of hibernate.cfg.xml in to my Web.config). Here is the relevant bits from my Web.config:

<configSections>
  <section name="combres" type="Combres.ConfigSectionSetting, Combres, Version=2.0.0.0, Culture=neutral, PublicKeyToken=49212d24adfbe4b4"/>
  <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>

<nhibernate 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">Data Source=(local)\SQLExpress;Initial Catalog=MyProject;Integrated Security=True</property>
    <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
    <property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
    <listener class="MyProject.Sql.Listeners.SaveEventListener, MyProject" type="save"/>
    <listener class="MyProject.Sql.Listeners.UpdateEventListener, MyProject" type="update"/>
  </session-factory>
</nhibernate>

In Global.asax, on Application_Start, I try to initialize my configuration:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    SessionProvider.Initialize();
}

All this really does is call new Configuration().Configure().AddAssembly("MyProject"); in accordance with the configuration code above.

Interesting result: When I first hit the page, an exception is thrown:

[FileNotFoundException: Could not find file 'D:\Build\MyProject\Source\MyProject.Web\bin\hibernate.cfg.xml'.]

Well, I put the configuration in Web.config, shouldn't it be lookign there? Do I need to indicate "hey, NHibernate, pay attention -- the config data is in Web.config, dummy!" anywhere?

When I then hit F5, the page comes up. Hurray! Now I try to do something with data access and I get this exception:

[ProxyFactoryFactoryNotConfiguredException: The ProxyFactoryFactory was not configured.
Initialize 'proxyfactory.factory_class' property of the session-factory configuration section with one of the available NHibernate.ByteCode providers.
Example:
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
Example:
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>]

Huh, that's kinda weird too -- this worked just fine in test with configuration in hibernate.cfg.xml...and I am specifying this property in my Web.config...I wonder what could possibly be up?

So, anyone have any ideas? Any help in solving this mystery would be super!

Update: I found the issue. It looks like I wasn't using the correct type in my configs section! D'oh. I have a complete write up on my blog at http://bit.ly/duj17B

A: 

Try calling the .Configure() method at the end:

new Configuration().AddAssembly("MyProject").Configure();

Or if you prefer put it into the web.config:

<nhibernate xmlns="urn:nhibernate-configuration-2.2">
  <session-factory name="">
    ...    
    <mapping assembly="MyProject" />
  </session-factory>
</nhibernate>

and then:

new Configuration().Configure();

Also make sure that the NHibernate.ByteCode.Castle.dll assembly is referenced in your web project.

Darin Dimitrov
Thanks Darin. I did as you suggested -- pushed my assembly mapping to the config file (Web.config) and modified my configuration method as above. Still no joy (same errors). Also, I'm indeed referencing the binaries *and* copying them locally. Any other ideas?
Brad Heller
A: 

It turns out that I was using the wrong type in the configuration section. You need to use NHibernate's section handler, not the generic .NET one. The behavior I was seeing was because it was all loaded in a singleton. On first visit, the configuration would fail. On subsequent visits it would just throw weird errors because the configuration failed originally!

There is one other caveat -- I have a complete writeup on my blog at http://bit.ly/duj17B

Brad Heller