Search code examples
.netnhibernatemappingnorthwind

Problem in mapping Northwind Customer with NHibernate


As a beginner on NHibernate (2.1.0), I am trying to set up my first unit test using the famous Northwind database. The test goes like this (the configuration files can be found at the end of this question) :

ISessionFactory sessionFactory=new Configuration().BuildSessionFactory();
ISession session=sessionFactory.OpenSession();
IList<Customer> list=session.CreateCriteria<Customer>().List<Customer>();
Assert.AreEqual(91, list.Count);

The problem is that list.Count is always 0.

  • I have tried to open the session by providing it my own IDbConnection, on Sql Server 2008, MS Access and SQLite (I am positively 100% sure that the database setups and the connections are valid) to no avail.
  • I have tried to make the generated SQL show up on the VS2008 output window (see config files at the bottom of this post) but nothing ever shows up.

I can only guess at this stage that my configuration is incorrect, but I have no idea how to fix it.


  • App.config :

    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
      <session-factory>
        <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>
        <property name="connection.connection_string">Data Source=S:\Work\SVN\src\Northwind\SQL\Northwind.db</property>
        <property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
        <property name="show_sql">true</property>
      </session-factory>
    </hibernate-configuration>
    <log4net>
      <appender name="DebugSQL" type="log4net.Appender.TraceAppender">
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
        </layout>
      </appender>
      <root>
        <level value="DEBUG" />
        <appender-ref ref="DebugSQL" />
      </root>
    </log4net>
    
  • Customer.cs :

    namespace Northwind.DomainModel.NHibernate
    {
        public class Customer
        {
            public string CustomerID { get; set; }
            public string CompanyName { get; set; }
            public string ContactName { get; set; }
            public string ContactTitle { get; set; }
            public string Address { get; set; }
            public string City { get; set; }
            public string Region { get; set; }
            public string PostalCode { get; set; }
            public string Country { get; set; }
            public string Phone { get; set; }
            public string Fax { get; set; }
        }
    }
    
  • Customer.hbm.xml :

    <hibernate-mapping
      xmlns="urn:nhibernate-mapping-2.2"
      assembly="Northwind.DomainModel"
      namespace="Northwind.DomainModel.NHibernate"
    >
      <class name="Customer" table="Customers">
        <id name="CustomerID" column="CustomerID" type="String" length="5">
          <generator class="assigned" />
        </id>
        <property name="CompanyName" />
        <property name="ContactName" />
        <property name="ContactTitle" />
        <property name="Address" />
        <property name="City" />
        <property name="Region" />
        <property name="PostalCode" />
        <property name="Country" />
        <property name="Phone" />
        <property name="Fax" />
      </class>
    </hibernate-mapping> 
    

Solution

  • Nailed it !

    It happens I wanted to play it smart and have the XML mapping file as a dependency of the CS file. In which case the embedded resource seems to bear the name of the first class contained in the CS file instead of the name of the XML file. An image being supposedly worth a thousand words : Solution and Assembly

    So I wrote this to get it to work :

    ISessionFactory sessionFactory=new Configuration()
        .Configure()
        .AddResource(typeof(Customer).FullName, typeof(Customer).Assembly)
        .BuildSessionFactory();
    

    Lessons learned in getting it to work :

    • NHibernate will not complain in any way when you try to use a class with no known mapping. I am not sure I would call that a feature...
    • Before opening a session with your own IDbConnection, open the connection itself.
    • You learn more than you intended to when trying to play smart ;-)