Configuring NHibernate in a Multiple Project Layout
I recently had to setup NHibernate in a multiple project c#, asp.net MVC solution. Since most of the tutorials and books only show a basic single project layout I thought I would post an example of how to configure NHiberate with a multi-project solution.
The main problem I had was that my model objects or entity objects were in a separate project than my database access code which contained the .hbm.xml mapping files. When I tried to configure NHibernate with the basic examples I was getting an “NHibernate.MappingException : No persister for: YourClass” exception. I was still getting that exception even after changing the .hbm.xml files to be an “Embedded Resource”. I finally figured out that my .hbm.xml files needed to reference the ModelLayer assebmly and my NHibernate.Cfg.Configuration.AddAssembly() needed to reference the DataAccessLayer assebmly. See screen shots and code examples below for more details.
Solution layout
- DataAccessLayer
- Duh. Database code
- References
- ModelLayer
- ModelLayer
- Model objects
- MvcAgain (web layer)
- ASP.Net project
- References
- ModelLayer
- ServiceLayer
- ServiceLayer
- Business logic
- Reusable logic
- References
- ModelLayer
- DataAccessLayer
Model objects Car.cs and CarLot.cs
using System.ComponentModel.DataAnnotations;
namespace MvcAgain.Models {
public class Car {
[Required]
public virtual int Id {get; set;}
[StringLength(35), Required]
public virtual string Manufacturer {get; set;}
[StringLength(35), Required]
public virtual string Model {get; set;}
public virtual CarLot Lot {get; set;}
}
}//end of Car.cs
using Iesi.Collections;
using System.ComponentModel.DataAnnotations;
namespace MvcAgain.Models {
public class CarLot {
[Required]
public virtual int Id { get; protected set; }
[StringLength(35), Required]
public virtual string Name { get; protected set; }
public virtual ISet Cars { get; protected set; }
}
}//end of CarLot.cs
Car.hbm.xml and CarLot.hbm.xml
These .hbm.xml files are in the DataAccessLayer project, but they reference the ModelLayer assembly.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="ModelLayer"
namespace="MvcAgain.Models">
<class name="MvcAgain.Models.Car" lazy="false" table="cars">
<id name="Id">
<generator class="native"/>
</id>
<property name="Model"/>
<property name="Manufacturer"/>
<many-to-one name="Lot" class="CarLot" column="lotid" not-null="true">
</many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="ModelLayer"
namespace="MvcAgain.Models">
<class name="MvcAgain.Models.CarLot" lazy="false" table="carlots">
<id name="Id">
<generator class="native"/>
</id>
<property name="Name"/>
<set name="Cars" inverse="true">
<key column="lotid"/>
<one-to-many class="Car"/>
</set>
</class>
</hibernate-mapping>
NHibernateSessionFactory.cs (NHibernate configuration code)
using NHibernate.Cfg;
using NHibernate;
namespace MvcAgain.DataAccessLayer {
public class NHibernateSessionFactory {
private static ISessionFactory sessionFactory = null;
private static ISessionFactory SessionFactory {
get {
if(sessionFactory == null) {
Configuration configuration = new Configuration();
configuration.Configure();
//note: you must use the name of the assembly
//that contains the .hbm.xml mapping files.
//For this example NHibernate will load all .hbm.xml files it
//finds in the DataAccessLayer assembly
configuration.AddAssembly("DataAccessLayer");
sessionFactory = configuration.BuildSessionFactory();
}
return sessionFactory;
}
}
public static ISession OpenSession() {
return SessionFactory.OpenSession();
}
}//end of class
}//end of namespace
ModelLayer assembly name in the properties pane.

Related Posts
Comments
2 Responses to “Configuring NHibernate in a Multiple Project Layout”
Leave a Reply
I have used this model for a while now, but I’m having trouble when a mapped class in my data access layer, for instance a association in my mapping file, relates to an object that is mapped in a separate solution, in a separate assembly, and hence in a separate namespace.
NHibernate gives me a runtime error stating that my one-to-many association refers to an unmapped class, even though my project references are correct and my class definitions embed the remote class correctly as a property.
The only solution I have found is to add the remote mapping to my project as an embedded resource, but I’m then left with a copy of the remote mapping in my project, and obviously this won’t be updated if the remote mapping changes.
Any ideas?
TIA
Ian
@Ian – Sorry Ian I don’t know the answer to that. I strongly suggest you post this question on http://stackoverflow.com/ and the nhibernate google group http://groups.google.com/group/nhusers/. I have received lots of help from both sites.