Different mechanisms to write the mappings

NHibernate has at least three different mechanisms for mapping persistent classes to database tables. This is both good and bad. While you can choose the one that you are most comfortable with, this can also leave you confused at times. Two of the mechanisms are natively supported by NHibernate library and one is an external implementation. In this section, we would look at all the three mechanisms briefly, before proceeding to implement mapping for our employee benefits problem. Though there are three different ways of expressing entity mappings, keep in mind that the core of the mapping engine is same, no matter which way you express your mappings. For all the mapping discussions in this chapter, I plan to express mappings using all the three methods in most of the cases. That way you will get a feel of how expressive each method is. It would not harm to stick to one method and ignore the others but remember that XML mappings are most complete and knowing them would always help in tricky situations.

Note

There is also a fourth mechanism which uses attributes. Here, attribute refers to the .NET construct and not the properties on entity. We will not be covering attribute-based mappings in this book. The main reason for this decision is that attribute-based approach adds NHibernate dependency to domain layer. As we will see in Chapter 8, Using NHibernate in a Real-world Application, domain layer should not depend on any infrastructure layer or code. We would prefer not to reference any NHibernate type from the domain model. This way we can prevent domain model from any accidental dependency on infrastructure code. But remember that this is in the context of a particular architectural principle I am choosing to follow. You might want to explore the attribute-based mappings on your own.

XML mappings

Mapping persistent classes to database using XML file is the oldest and original method of writing mapping. This is what was first supported by Hibernate and NHibernate ported it as is. In this method, you write mapping information in an XML file using custom elements and attributes made available by NHibernate.

As we will see in this chapter and in the coming chapters, mappings can become quite detailed and intricate as your business requirements grow in complexity. The biggest advantage of XML mappings is that you can express mappings for every feature that NHibernate supports. Other two mechanisms have some limitations in supporting every feature of NHibernate. For instance, mapping of a protected attribute is no different than mapping of a public attribute when it comes to XML mappings. For the other two mechanisms, the same is not true. Think of XML mappings as superset of all mapping features.

While there are some clear advantages of using XML mappings, there are some disadvantages too. Most frowned upon is that XML mappings are not refactoring friendly. As we will see in this chapter, XML mappings use lot of magic strings to refer to classes and attributes. This may lead to subtle defects when you rename a class or attribute but forget to update the magic strings XML mappings. I personally do not see that as much of a problem if you have well written unit tests that warn you of failing code every time you change something. You still have to manually update the XML files but at least it saves you the embarrassment of a broken feature after your commit.

Fluent mapping

XML was the hero of its time but soon the fame was waning and the development community was looking at non-XML options for everything. NHibernate was still only supporting XML mappings. Some enthusiastic developers decided to build a new mechanism for mapping persistent classes. They built a library named Fluent NHibernate (FNH). If I could quote from FNH's website (http://www.fluentnhibernate.org/), this is how they describe FNH:

"Fluent, XML-less, compile safe, automated, convention-based mappings for NHibernate."

With FNH, you do not need to write a single line of XML. All you use is their fluent API. So far, this is the most famous non-XML mechanism for writing mappings.

FNH manages to avoid magic strings to refer to classes and attributes by using lambda expressions. But that adds constraints as lambdas only have access to public properties. If you want to map protected/private properties then FNH offers a few ways, but none are as elegant. Another thing to note about FNH is their choice of naming. Developers of FNH chose to use different names from the ones used in XML to represent mappings. For instance, to map an attribute, XML uses property whereas FNH uses map. This may cause confusion in the beginning if you are going from FNH to XML or vice versa.

Mapping by code

FNH became so famous that authors of NHibernate felt a need to support FNH natively in NH. But the fact that FNH API deviated significantly from XML conventions was an issue. NHibernate team wanted an API that is closer to XML conventions. Another open source library called ConfORM was able to achieve this and authors of NHibernate took inspiration from ConfORM's style to build support for mapping by code. Version 3.2 is the first version released with such support but implementation was not finished and hence it never got the level of adoption that other methods have got. Latest release of NHibernate has number of fixes in the area of mapping by code, making it quite stable.

API of mapping by code conforms to the naming convention and structure of XML mappings. The names of the methods used to declare mappings match with corresponding XML element names. All API methods fundamentally accept two parameters (with several overloads to accommodate for edge cases). The first one is attribute being mapped and second one is a lambda that can be used to declare additional mapping information. This closely follows the way XML mappings are declared.

I must say that this is not the better API in comparison to FNH as it is very XML-like and you cannot write mapping code without thorough understanding of XML mappings. One good thing about mapping by code is that it lets you map private properties/fields through specifically provided overrides and some lambda tricks. While this seems to fix a problem, remember that it also makes the mappings less refactor-friendly. But if you are unable to use FNH for any reason and do not want to use XML mappings for their refactor unfriendly nature, then mapping by code can be a good choice.

We will look at mapping our employee benefits domain using all the three methods. We will begin with XML mappings first where we would deep dive into understanding how to write mappings for different scenarios. We will then go on to rewrite the same mappings using the other two techniques.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset