NHibernate.BusinessObjects - Tutorial Part 1
Introduction to NHibernate.BusinessObjects
NHibernate.BusinessObjects is an easy to use business layer that wraps the object-relational mapper (ORM) NHibernate.
This tutorial is about using NHibernate.BusinessObjects, it does not explain how to use NHibernate.
NHibernate.BusinessObjects is a business layer for Winforms or WPF client applications. It should not be used for
web applications.
This article contains the first steps to get started with NHibernate.BusinessObjects by a short example-project.
You don't need any knowledge obout NHibernate to run your first NHBO-Application but I will explain it if needed for
your further understanding.
You can either follow the steps described in the tutorial to create the project or you can download the complete sources for this tutorial.
Getting started
First you need to download the latest version of NHibernate.BusinessObjects from
sourceforge.net/projects/nhbusinessobj
Create a new folder for the project, e.g. Tutorial Part 1. Open
this folder and create the subfolders bin and
Source.
After unzipping the file into the bin folder you will find
everything you need to build your first NHibernate.BusinessObjects
application.
Creating the data model
The data model describes the structure of your business domain. The descriptions contains of a set of description files. You can create one description file for all business objects, but it is best practice to create one description file for each object.
In the Source folder create a new subfolder DataModel. From the bin\Configuration folder copy the schema file "BusinessObjectsStructure.xsd" to the DataModel folder. You don't need the schema file but it will activate intellisense if you create the description files with Visual Studio.
Now create a new XML file and name it "Tutorial.Person.bo.xml". All
description files must have the extension ".bo.xml". A good naming
style is namespace.type.bo.xml.
Add the following content to the file.
The Namespace attribute of the BusinessObjects element determines the namespace for the generated C# code. The BusinessObjects element can contain one or more Type elements. I recommend to define one type per description file. The Type element contains a list of Property definitions. Here we have the properties "Id", "Name", "FirstName", and "Age".
Generating the business objects
Now it's time to generate the business objects. Open a console
window and change the directory to the bin
folder.
Call the NHibernate.BusinessObjects.Generator.exe. As parameter you
need to assign the path to the description files and to the target
folder.
NHibernate.BusinessObjects.Generator.exe /d:..\Source\DataModel /t:..\Source\Generated
Open the folder Source\Generated. You will find a new folder named "Tutorial" that contains the generated Visual Studio 2008 and 2010 projects. The projects contains the interfaces and implementations for the business objects and the NHibernate mapping files.
Creating a solution
Next step is to create a Visual Studio solution in the Source folder. Open the solution and add the generated project. Then create a new project. Choose "Visual C# - Windows - Console Application" as project type. Set the project name to "Console".
From the bin folder add the following assembly references to the Console project:
- Antlr3.Runtime.dll
- Iesi.Collections.dll
- LinFu.DynamicProxy.dll
- log4net.dll
- NHibernate.BusinessObjects.dll
- NHibernate.ByteCode.LinFu.dll
- NHibernate.dll
- NHibernate.Linq.dll
Further, add the generated project as project reference to the Console project and add the NHibernate configuration file "Hibernate.cfg.xml" from the bin\Configuration folder to the project. Finally set the Copy to Output Directory property for the configuration file to "Copy always".
Creating a new database
Open the Microsoft SQL Server Management Studio and connect it to your preferred SQL Server. Create a new database and set the name to "Tutorial". You don't need to create any tables. NHibernate.BusinessObjects uses NHibernate to create the tables automatically.
Accessing the data
In the Console project open the file "Program.cs" and add the following usings:
In the Main method add the code below.
A business document represents the underlying database. We use the business document factory to create an instance
of a document. When creating a new document, you have to assign a list of business object description files (.bo.xml)
to the CreateDocument method.
Call Create on the document. Pass the
server and database name to the method. If you don't have integrated
security enabled for the database, you have to provide the user name
and the password. Internally, Create forces NHibernate to create
all tables for the database. If the tables have already been created before, NHibernate will delete these tables and create
new ones. This is useful for development and testing when you always
need an empty database. Once the tables are created, you can use the
Open method to open the database without
replacing the tables. Open will be typically the method you
use in your application when the user requests access to the database.
In the next step I will show you how to create a new business object. Add a method CreatePerson as shown in the next picture.
In the Main method add a call to CraetePerson.
After you have created the Person object, you need a way to read the object from the database. Therefore we create a method GetPersonsByName and use LINQ to query the data. NHibernate.BusinessObjects does not implement LINQ. Instead it uses NHibernate's implementation of LINQ.
Finally we have to add a call to the new method.
You can now build the solution and run the Console application.
Using Business Sessions
I think, this tutorial is a good place to go a little bit deeper into the business session, since this is an essential part of NHibernate.BusinessObjects.
Business session are not used in the way you would use a session in NHibernate. In web applications it is important to release
resources such as database connections as soon as possible. By using NHibernate in your web application, you
typically
create a session per request to achieve this.
In a client application, you open a session when the user logs on to the system and you
close it, when the user logs off. But there are some drawbacks with that approach when using a NHibernate session: Over the time,
the session's chache contains more and more business objects and in the worst case the session holds the complete database in memory.
There are further issues why you can't keep open NHibernates session
the whole time while the user is looged on. I will explain them -
and the solutions - in a later article.
Opening and closing a session
To open a session, call OpenSession on a business document. Call session.Close if you don't need the session anymore. Call Dispose after you have closed the session. If you call Dispose on an open session, it will be closed automatically. In case you close a session while a tranaction is still in use, the transaction will be rolled back.
Threading
A session is always bound to the thread in which it has been opened. Therefore, business objects belonging to the session can only be modified in that thread. Any modification of a business object in another thread causes an exception. To modify data in another thread, you have to open a new session in the accordingly thread and then to get the object from the database. Changes on a business object in one thread will not affect the business objects representing the same data in other threads. When you need the newest data in another thread, you can call Reload on the object to retrieve the updated data.
To retrieve the session associated with the current thread, use the business document's CurrentSession property.
Singleness of business objects
If you retrieve an object from NHibernate and then close the NHibernate session, the object will be detached from the session. If you want to do any changes, you have to reattach that object to a session. There are some problems with that approach in client applications: If you detach a business object, the GUI may still have a reference to the object. If you now execute a query on a new session, the session may return a new instance of the object. That means, you have now two instances of business objects representing the same row in database. If the data have changed in the meantime, you even may have different data. This is an unacceptable behaviour in client applications. To solve this problem, you have to reattach all objects referenced in your application to a session before executing any query. Since your application can keep references to thousands of objects this won't be the preferred solution. The business session can handle this issue, so you don't need to worry about.
Next...
In the next part of this tutorial, I will show you how to create associations between business objects. I'll also explain the difference between child/parent and reference relationships and how to use them with NHibernate.BusinessObjects.