nHibernate is something I used for 1 project over 5 years ago when I wanted to pull geospatial data from a PostgreSql database. It was straight forward to use and wasn’t as bound to a database as Entity Framework (EF) was at the time, and its performance was great.
Since then I have been using EF for Object Relational Mapping (ORM) tasks and have largely forgotten how to use nHibernate.
Recently I have moved to a outfit that use nHibernate, so I decided to refresh my understanding by adding nhibernate into a project I am working on at home.
I had a repository class that I had quickly set up using SQLCommand to query a test database, which I replaced with NHibernate mapping. The simple classes, where I queried one table worked fine and were easy to setup, however when I tried to set up a more complex example with 2 tables linked by a foreign key and a many-to-one relationship I came across an error in my unit testing.
I came across the error when testing the repository class for a class called Income. The class had several properties that mapped to columns in the income table and a PaymentType property, that mapped to a PaymentTypeId column in the income table and a PaymentType table by foreign key. I had mapped this in the mapping xml as a many to one relationship, with PaymentTypeId in the Income database table being the key.
The error was:
nhibernate.mappingexception: could not determine type for finance entities.payment type, finance entities for columns nhibernate.mapping.column(paymenttype)
To start with I thought there was a problem with how I had defined the relationship, so I tried setting it up as a join, or adding a ISet of Incomes to the PaymenType class and mapping as a Set in the PaymentType mapping xml.
I was still getting the same error, so did a little googling and noticed in an example of a nHibernate POCO, that the serializable attribute had been added to the class. When I added this to the PaymentType class and reran my tests they passed – happy days!
So why was this needed? Especially when all the tutorials I had looked at had never mentioned needing to set classes as serializable.
Serializable is what allows types to be sent over networks, hence why it is often used with web services. NHibernate maps properties to database types depending on the database type. Simple types like strings and integers can be mapped straight forwardly to varchars and databases Integers. .Net complex objects however are not so straight forward, NHibernate handles these by serialising the object and mapping the properties of the complex object to a database table.
This is why the PaymentType class needed to be set to Serializable and the Income class did not.
NHibernate requires a class to have the Serializable attribute, if that class is used as a property in another mapped class.