Question

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> 
    
Was it helpful?

Solution 3

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 ;-)

OTHER TIPS

My first step to troubleshooting this would be to ask what sql is being generated by your call and then attempt to run that against the target db and see what results you get

You might need to change your appender to a console appender rather than trace.

two things you need to call configure on your configuration object like this :

   
Configuration configuration = new Configuration().Configure();

this expect a file named Hibernate.cfg.xml in the same directory. There's another method you can call to specify the name of config file if you have another name.

Second you need to tell NHibernate where to load the mapping files, which assembly before creating the factory


configuration.AddAssembly(typeof(Customer).Assembly); //if in same assembly with  customer class

Finally all members of your customer class should be virtual else you can't use lazy loading.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top