NHibernate in Details: Part 1

Introduction

 
NHibernate is
  • An open-source ORM framework.
  • Designed to serve as a persistence layer exclusively for the .Net framework based on Object-Relational Mapping Technique.
  • A tool that creates a "virtual representation" of database objects within the code.
  • Used to solve the problem of impedance mismatch between Class and relational databases and tables.
A few words
 
When exploring the concept of Hibernate in Java a few years ago a thought came to my mind. How can we use Hibernate with .NET or another programming language? Do we need to use it in the same way or need to change or convert it using third-party tools? Then I decided to explore it more and start writing a series on it, to cover each and every aspect of it. This is Part I of this series and later will be Part 2 and more (a total of 10 parts) in which we will learn about hibernating configuration, mapping (1-1, 1- n, n-n), query and criteria expression as well, in a simple and efficient manner.
 
According to the creators of NHibernate:
 
NHibernate is a port of the Hibernate Core for Java to the .NET Framework. It handles persisting plain .NET objects to and from an underlying relational database. Given an XML description of your entities and relationships, NHibernate automatically generates SQL for loading and storing the objects.
 
How it was started (According to Wikipedia)
 
NHibernate was started by Tom Barrett and further developed by Mike Doerfler and Peter Smulovics. At the end of 2005, JBoss, Inc. hired Sergey Koshcheyev to work full-time on its future versions. At the end of 2006, JBoss stopped the support of the project; it is now entirely developed and led by the community.
 
The quick-release and version chart are:
 
Databases support available in NHibernate
 
The database engines supported by NHibernate include:
  • Microsoft SQL Server.
  • Windows Azure SQL Database Object Linking and Embedding (OLE).
  • Oracle.
  • MySQL.
  • Postgres.
Object-relational mapping (ORM, O/RM, and O/R mapping)
 
It is a technique for creating a layer to map data among classes and relational databases. This creates, in effect, a "virtual object database" that can be used from within the programming language.
 
For example, when we develop a project using any OOP language there's a mismatch between the object model and the relational database. This is because an RDBMS represents data in a tabular format whereas object-oriented languages, such as Java and C# represent data as objects.
 
The Object-Relational Mapping (ORM) is the solution to handle the mismatches as listed below.
  • Problem of Granularity: We can have more classes than database tables.
     
  • Problem of Inheritance: A database does not support inheritance.
     
  • Problem of Associations/composition: They cannot be easily represented in a database.
     
  • Problem of Impedance mismatch: The mismatch between structural and data type representation in classes and databases.
Impedance mismatch
 
For example, consider the following class with properties and Employee table with column and data type:
 
 
It is clear from the preceding example that they differ in structure and data type representations (we will review in more detail in later series).
 
Now we can say that using Hibernate we can map each and every property of the Class with the relational table.
 
Thus NHibernate can offer the following advantages:
  • Persist the object in the relation database and can do all CRUD operations in it.
  • NHibernate does all the database work.
  • Eliminates the necessity to write SQL statements or create a stored query.
  • We can have all of our data access logic contained within our application.
  • Data Cartography, not only will our queries be effective, but they will also be validated by the compiler. Therefore, if our underlying table structure changes, the compiler will alert us that we need to change our queries!
  • For all Create, Retrieve, Update, and Delete (CRUD) there is no need to write a SQL query.
Other open-source ORM solutions include:
  • Hibernate
  • Spring DAO
  • EJB: Enterprise JavaBeans Entity Beans
  • Java Data Objects: JDO
  • TopLink
  • Java Persistent API: JPA
Where to get it
 
The sources from where we can download the NHibernate DLL are:
  • NuGet.
  • As source code from the GitHub repository.
  • As a downloadable Zip package from SourceForge.
The home of the NHibernate project is at http://www.nhforge.org, whereas the code is housed at SourceForge (http://sourceforge.net/projects/nhibernate/).
 
The stable format can be download as:
 
NHibernate-3.3.1.GA-bin: Zip file format
 
NHibernate-2.1.2.GA-bin: Zip file format
 
On Visual Studio 2013, use the Package Manager Console and enter the following command:
 
 
Thus we need to understand:
  • What HBM mapping files are and what they are used for.
     
  • What are Plain Old CLR Objects (POCOs) that NHibernate actually maps data into?
     
  • How the Data Access Object (DAO) classes are used to tell NHibernate to retrieve or save the data we are working with.
     
  • How to retrieve data in a web page that was data-bound to a collection of NHibernate objects, all without any code-behind or other additional code.
A basic NHibernate project is divided into major parts.
 
An NHibernate project is composed of multiple elements such as:
  1. The XML mapping files (hbm.xml).
  2. Hibernate Configuration File: hibernate.cfg.
  3. Plain Old CLR Objects (POCOs).
  4. Web.config (An XML File).
  5. Database with Data Access Object (DAO).
  6. Web page / WebForm / MVC: View (Razor).
But a basic NHibernate project is composed of the following three major parts.
  1. Hibernate Mapping File: To map data to POCOs
     
    • To tell NHibernate how the database is or should be constructed.
    • Data access methods to tell NHibernate what data you want to retrieve or store into the database.
    • A POCO to allow you to interact with the data. Whereas XML mapping files are commonly used in NHibernate projects, they are not the only way to map data to POCOs.
       
  2. Hibernate Configuration File: hibernate.cfg
     
    • Provide information about the configuration used to connect to the database, the dialect used for the SQL query, the session factory class and so on.
    • NHibernate basically depends upon the "sessionFactory", a thread-safe object built once per application lifetime.
    • A Hibernated mapping file, based on the configuration that controls how database tables are mapped to C# objects. In other words which property maps to which column in a database table.
    • An XML file for hibernate mapping
       
  3. Plain Old CLR Objects (POCO)
     
    • To create a class in C# or VB.NET.
    • A class can have only a property marked as Virtual (It helps hibernate to create a proxy).
    • It can have a default constructor.
       
  4. Main Class / View Pages in aspx
     
    • To work with the Session to get and set the data into the session to be persisted into the database.
    • To use the session for retrieving and displaying the data from the database to the aspx page or VIEW page.
How to develop Project using Visual Studio - 2013
  1. The First Step: To create the database table such as “Employee”.
     
    Create a database table to map against the class (POCO). We define a table named Employee with a Primary Key column named Id and nullable fields to store the FirstName, LastName, and Designation.
     
    Employee table
     
     
  2. The Second Step
     
    1. Create a Web Project
       
      First, we need to create a new Web project. We use the name EMPNHibernate, the project web virtual directory will http://localhost/EMPHibernate.
       
    2. Add NHibernate.dll reference
       
      In the project, add a reference to NHibernate.dll. Visual Studio will automatically copy the library and its dependencies to the project output directory. If you are using a database other than SQL Server, add a reference to the driver assembly to your project.
       
    3. To Create the XML mapping file (hbm.xml)
      1. <?xml version="1.0" encoding="utf-8" ?>  
      2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="EMPNHibernate" namespace="EMPNHibernate.Models">  
      3.   <class name="Employee" table="Employee" dynamic-update="true" xmlns="urn:nhibernate-mapping-2.2">  
      4.     <cache usage="read-write"/>  
      5.     <id name="Id" column="Id" type="int">  
      6.       <generator class="native" />  
      7.     </id>  
      8.     <property name="FirstName" />  
      9.     <property name="LastName" />  
      10.     <property name="Designation" />   
      11.    </class>  
      12. </hibernate-mapping>  
    4. Create an entry in Web.config or create a separate file hibernate.cfg.xml
      1. <configuration>  
      2.   <configSections>  
      3.     <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate"></section>  
      4.    </configSections>  
      5.     
      6.   <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">  
      7.     <session-factory>  
      8.       <property name="hbm2ddl.auto">update</property>  
      9.       <property name="connection.provider">  
      10.         NHibernate.Connection.DriverConnectionProvider  
      11.       </property>  
      12.       <property name="dialect">  
      13.         NHibernate.Dialect.MsSql2008Dialect  
      14.       </property>  
      15.       <property name="connection.driver_class">  
      16.         NHibernate.Driver.SqlClientDriver  
      17.       </property>  
      18.       <property name="connection.connection_string">  
      19.         Data Source=(local);Integrated Security=True; initial catalog=Test  
      20.       </property>  
      21.       <property name="show_sql">  
      22.         true  
      23.       </property>  
      24.       <mapping assembly="EMPNHibernate" />  
      25.     </session-factory>  
      26.   </hibernate-configuration>  
  3. POCO: Now create a simple class “Employee” using Add new item
     
    Employee Class
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Web;  
    5.   
    6. namespace EMPNHibernate.Models  
    7. {  
    8.     public class Employee  
    9.     {  
    10.         public virtual int Id { getset; }  
    11.         public virtual string FirstName { getset; }  
    12.         public virtual string LastName { getset; }  
    13.         public virtual string Designation { getset; }  
    14.     }  
    15. }  
  4. Create a Main Class or ASPX Page
     
    1. First, create NHibernate Session Factory class
       
      This is the class that could be used as a singleton.
      1. using System.Web;  
      2. using NHibernate;  
      3. using NHibernate.Cfg;  
      4.   
      5. namespace EMPNHibernate  
      6. {  
      7.     public class NHibertnateSession  
      8.     {  
      9.         public static ISession OpenSession()  
      10.         {  
      11.             var configuration = new Configuration();  
      12.             configuration.Configure();  
      13.             ISessionFactory sessionFactory = configuration.BuildSessionFactory();  
      14.             return sessionFactory.OpenSession();  
      15.         }  
      16.     }  
      17. }  
    2. Create an ASPX page using the Add New Item option
       
      The following procedure can be done to use the NHibernate SessionFactory.
       
      In the button click event of the page:
       
      • Open the Session with SessionFactory.
      • Instantiate the Object.
      • Get Data from TextBox and relate it with the object property.
      • Save the Data into the Database.
      • Close the Session.
      1. protected void btnSubmit_Click(object sender, EventArgs e)  
      2. {  
      3. ISession session = NHibertnateSession.OpenSession();  
      4.   
      5. Employee emp = new Employee();  
      6. emp.FirstName = txtName.Text;  
      7. emp.LastName = txtLastName.Text;  
      8. emp.Designation = txtDes.Text;  
      9. session.Save(emp);  
      10. session.Close();  
      11. }  
Part 2 will explore the basic concepts in detail.