0

I tried an example from NHibernate in Action book and when I try to run the app, it throws an exception saying "Could not compile the mapping document:

HelloNHibernate.Employee.hbm.xml"

Below is my code,

Employee.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true">
<class name="HelloNHibernate.Employee, HelloNHibernate" lazy="false" table="Employee">
<id name="id" access="field">
  <generator class="native"/>
</id>
<property name="name" access="field" column="name"/>
<many-to-one access="field" name="manager" column="manager" cascade="all"/>
</class>
</hibernate-mapping>

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using System.Reflection;
using NHibernate.Cfg;

namespace HelloNHibernate
{
class Program
{
    static void Main(string[] args)
    {
        CreateEmployeeAndSaveToDatabase();
        UpdateTobinAndAssignPierreHenriAsManager();
        LoadEmployeesFromDatabase();

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }

    static void CreateEmployeeAndSaveToDatabase()
    {
        Employee tobin = new Employee();
        tobin.name = "Tobin Harris";

        using (ISession session = OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                session.Save(tobin);
                transaction.Commit();
            }
            Console.WriteLine("Saved Tobin to the database");
        }
    }

    static ISession OpenSession()
    {
        if (factory == null)
        {
            Configuration c = new Configuration();
            c.AddAssembly(Assembly.GetCallingAssembly());
            factory = c.BuildSessionFactory();
        }
        return factory.OpenSession();
    }

    static void LoadEmployeesFromDatabase()
    {
        using (ISession session = OpenSession())
        {
            IQuery query = session.CreateQuery("from Employee as emp order by emp.name asc");

            IList<Employee> foundEmployees = query.List<Employee>();

            Console.WriteLine("\n{0} employees found:", foundEmployees.Count);

            foreach (Employee employee in foundEmployees)
                Console.WriteLine(employee.SayHello());
        }
    }

    static void UpdateTobinAndAssignPierreHenriAsManager()
    {
        using (ISession session = OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                IQuery q = session.CreateQuery("from Employee where name='Tobin Harris'");

                Employee tobin = q.List<Employee>()[0];
                tobin.name = "Tobin David Harris";

                Employee pierreHenri = new Employee();
                pierreHenri.name = "Pierre Henri Kuate";

                tobin.manager = pierreHenri;
                transaction.Commit();

                Console.WriteLine("Updated Tobin and added Pierre Henri");
            }
        }
    }

    static ISessionFactory factory;
}
}

Employee.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HelloNHibernate
{
class Employee
{
    public int id;
    public string name;
    public Employee manager;

    public string SayHello()
    {
        return string.Format("'Hello World!', said {0}.", name);
    }
}
}

App.config

    <?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral
             PublicKeyToken=b77a5c561934e089"/>
  </configSections>
  <nhibernate>
    <add key="hibernate.show_sql" value="false"/>
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
    <add key="hibernate.connection.connection_string" value="Server=(local)\SQLEXPRESS; Database=HelloNHibernate;Integrated Security=SSPI;"/>
  </nhibernate>
</configuration>
developer
  • 5,178
  • 11
  • 47
  • 72

3 Answers3

1

Let's open the Matryoshka doll a bit further, and solve the other problem:

In this line:

<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0, Culture=neutral PublicKeyToken=b77a5c561934e089"/>

you're missing a comma between "neutral" and "PublicKeyToken".

Give that a try.

  • I changed it to the above line and now it gives the below error, Could not compile the mapping document: HelloNHibernate.Employee.hbm.xml which it gave previously.. – developer Apr 15 '10 at 16:30
  • Hey, it worked after I changed the manager field mapping from property to many-to-one. Thanks a lot for all your help:) – developer Apr 15 '10 at 16:36
0

Do you have a manager class and mapping defined? The

<many-to-one access="field" name="manager" column="manager" cascade="all"/>

line is looking for one. If the "manager" field is supposed to be an Employee, then you probably want:

<many-to-one access="field" name="manager" column="manager" class="HelloNHibernate.Employee, HelloNHibernate" cascade="all"/>

  • No manager is only a field in table Employee. So I tried changing the line to simple but now I get the below error. Could not compile the mapping document: HelloNHibernate.Employee.hbm.xml – developer Apr 14 '10 at 21:01
  • I also tried using the above line that you have posted but I still get that error. – developer Apr 14 '10 at 21:01
0

I think I see the problem now. The problem appears to be in this line:

<add key="hibernate.connection.connection_string" value="SQL2008EXPRESS" Database="HelloNHibernate;Integrated Security=SSPI;User Id=SQL2008"/>

The connection string is malformed, and it's throwing off the XML parser. Since the "value" attribute ends early, the XML parser thinks "Database=" is another XML attribute, but it's not one it recognizes, so it chokes. The solution is to fix the connection string.

The line should probably read:

<add key="hibernate.connection.connection_string" value="Server=(local)\SQLEXPRESS; Database=HelloNHibernate;Integrated Security=SSPI;"/>

This is assuming you're using Windows authentication; given that this is a learning project, that's probably the best way to go. If you're using SQL Server authentication, use this line instead:

<add key="hibernate.connection.connection_string" value="Server=(local)\SQLEXPRESS; Database=HelloNHibernate; User Id=theusername; Password=thepassword"/>

An aside: I don't think NHibernate 1.2.1GA has a SQL Server 2008 dialect. Instead, use NHibernate.Dialect.MsSql2005Dialect.

  • I am using windows authentication and I tried changing App.config to above edited file, and now I get error that says 'The type initializer for 'NHibernate.Cfg.Environment' threw an exception'. This is so confusing.. – developer Apr 15 '10 at 14:06
  • Does it include an inner exception? That'd be more useful for diagnosing the problem. – Benjamin Geiger Apr 15 '10 at 15:53
  • Below is the inner exception detail {"An error occurred creating the configuration section handler for nhibernate: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047) (C:\\My Documents\\Visual Studio 2008\\Projects\\HelloNHibernate\\HelloNHibernate\\HelloNHibernate\\bin\\Debug\\HelloNHibernate.vshost.exe.Config line 4)"} – developer Apr 15 '10 at 16:03