To go alongside my set of posts on LINQ To SQL I wanted to post an Introduction to NHibernate. These posts are not intended as any kind of masterclass, so experienced NHibernate hands might want to skip them. They are intended for folks who are new to the framework to help get them started.
In this first session we will introduce NHIbernate and the basics of mapping.* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-1610611985 1073750139 0 0 159 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-update:auto;
mso-style-parent:””;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:10.0pt;
mso-bidi-font-size:12.0pt;
font-family:Calibri;
mso-fareast-font-family:”Times New Roman”;
mso-bidi-font-family:”Times New Roman”;
mso-bidi-font-weight:bold;}
h1
{mso-style-name:”Heading 1\,min1″;
mso-style-update:auto;
mso-style-next:”Body Text Indent”;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:2.0cm;
text-indent:-2.0cm;
mso-pagination:widow-orphan lines-together;
page-break-after:avoid;
mso-outline-level:1;
mso-list:l0 level1 lfo1;
tab-stops:36.0pt list 2.0cm;
font-size:18.0pt;
mso-bidi-font-size:10.0pt;
font-family:Arial;
mso-bidi-font-family:”Times New Roman”;
mso-font-kerning:0pt;
mso-fareast-language:EN-US;}
h2
{mso-style-update:auto;
mso-style-next:Normal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:2;
font-size:14.0pt;
font-family:Arial;
mso-bidi-font-weight:normal;
mso-bidi-font-style:italic;}
h3
{mso-style-update:auto;
mso-style-next:Normal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-outline-level:3;
font-size:11.0pt;
mso-bidi-font-size:13.0pt;
font-family:Arial;
mso-ansi-language:EN-US;
mso-fareast-language:EN-US;
mso-bidi-font-weight:normal;}
p.MsoBodyTextIndent, li.MsoBodyTextIndent, div.MsoBodyTextIndent
{mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:14.15pt;
mso-pagination:widow-orphan;
mso-outline-level:3;
font-size:10.0pt;
mso-bidi-font-size:12.0pt;
font-family:Calibri;
mso-fareast-font-family:”Times New Roman”;
mso-bidi-font-family:”Times New Roman”;
mso-bidi-font-weight:bold;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
/* List Definitions */
@list l0
{mso-list-id:887691598;
mso-list-template-ids:-1967875248;}
@list l0:level1
{mso-level-start-at:0;
mso-level-style-link:”Heading 1″;
mso-level-text:%1;
mso-level-tab-stop:2.0cm;
mso-level-number-position:left;
margin-left:2.0cm;
text-indent:-2.0cm;}
@list l0:level2
{mso-level-text:”%1\.%2″;
mso-level-tab-stop:2.0cm;
mso-level-number-position:left;
margin-left:2.0cm;
text-indent:-2.0cm;}
@list l0:level3
{mso-level-text:”%1\.%2\.%3″;
mso-level-tab-stop:2.0cm;
mso-level-number-position:left;
margin-left:2.0cm;
text-indent:-2.0cm;}
@list l0:level4
{mso-level-text:”%1\.%2\.%3\.%4″;
mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
margin-left:53.85pt;
text-indent:-53.85pt;}
@list l0:level5
{mso-level-text:”%1\.%2\.%3\.%4\.%5″;
mso-level-tab-stop:50.4pt;
mso-level-number-position:left;
margin-left:50.4pt;
text-indent:-50.4pt;}
@list l0:level6
{mso-level-text:”%1\.%2\.%3\.%4\.%5\.%6″;
mso-level-tab-stop:57.6pt;
mso-level-number-position:left;
margin-left:57.6pt;
text-indent:-57.6pt;}
@list l0:level7
{mso-level-text:”%1\.%2\.%3\.%4\.%5\.%6\.%7″;
mso-level-tab-stop:64.8pt;
mso-level-number-position:left;
margin-left:64.8pt;
text-indent:-64.8pt;}
@list l0:level8
{mso-level-text:”%1\.%2\.%3\.%4\.%5\.%6\.%7\.%8″;
mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
margin-left:72.0pt;
text-indent:-72.0pt;}
@list l0:level9
{mso-level-text:”%1\.%2\.%3\.%4\.%5\.%6\.%7\.%8\.%9″;
mso-level-tab-stop:79.2pt;
mso-level-number-position:left;
margin-left:79.2pt;
text-indent:-79.2pt;}
–>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:”Table Normal”;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-parent:””;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.0pt;
font-family:”Times New Roman”;
mso-ansi-language:#0400;
mso-fareast-language:#0400;
mso-bidi-language:#0400;}
Where, who what, when, why?
NHibernate is an open source ORM, derived initially from the
Hibernate project. NHibernate supports persistence ignorance, your object
classes don’t have to follow a restrictive programming model. Persistent
classes do not need to implement any interface or inherit from a special base
class.Hibernate was developed by a team of Java software
developers around the world led by Gavin King.
NHibernate 2.0.1GA is the current version of NHIbernate.
Building NHibernate
You can just download the binaries that you need, especially
if you have no appetite for un-released versions, however if you want the
latest features then you need to download the latest version of the source and
build it.
The NHibernate source code can be found on sourceforge. The
easiest way to get hold of it is to use a Subversion (SVN) client such as
TortoiseSVN to download the code from the repository. NHibernate lives at:
https://nhibernate.svn.sourceforge.net/svnroot/nhibernate/trunk/nhibernate/
Just run Nant in trunk/NHibernate directory to build. Check
the options file if you want to see different ways of building.
Working with Visual Studio
You can also open the source using the supplied Visual
Studio solution file; this allows you to run tests, submit patches etc. Ignore
the ‘customized project’ warning as this is a trusted source.
Mapping with NHibernate
Initialization
There are four steps to getting NHibernate working:
Provide information to access the database
Configure log4net
Provide the mapping information of the entities and value
types
Build the session factory
Accessing the Db
We need to modify our config file to tell our application
how to initialize NHibernate. We can do this in a separate config file, or, my
preferred option, from within the app.config file. You can copy the
nhibernate-configuration.xsd file into the visual studio
common7/packages/schemas/xml file to get intellisense for writing NHibernate
configuration information.
We set four properties to access the database:
ConnectionProvider: This value never changes.
Dialect: This depends on your database
ConnectionDriver: This depends on your database.
ConnectionString: The string used to create a database
connection.
<?xml version=”1.0″ encoding=”utf-8″
?>
<configuration>
<configSections>
<section name=”hibernate-configuration”
type=”NHibernate.Cfg.ConfigurationSectionHandler,NHibernate”
/>
<section name=”log4net”
type=”log4net.Config.Log4NetConfigurationSectionHandler,log4net”
/>
</configSections>
<hibernate-configuration xmlns=”urn:nhibernate-configuration-2.2″>
<session-factory>
<property name=”connection.provider”>
NHibernate.Connection.DriverConnectionProvider
</property>
<property name=”dialect”>
NHibernate.Dialect.MsSql2000Dialect
</property>
<property name=”connection.driver_class”>
NHibernate.Driver.SqlClientDriver
</property>
<property name=”connection.connection_string”>
Initial
Catalog=nhibernate;Integrated Security=SSPI
</property>
</session-factory>
</hibernate-configuration>
</configuration>
This allows us to create a NHibernate SessionFactory. The SessionFactory
is an expensive resource to initialize, so we only want one. Crudely for this
example we just make it a static member of the class. But the key is to
understand that you create the SessionFactory once, at start up, and then
create sessions from the factory when you need to interact with persistent
entities.
public class Program
{
private static ISessionFactory sessionFactory = null;
public static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
Configuration cfg = new Configuration();
cfg.Configure();
sessionFactory = cfg.BuildSessionFactory();
}
Configuring log4net
NHibernate uses log4net for logging so it is worth setting
up log4net so that you can see any errors that are generated. Configuration in
NHibernate can be a little painful and frustrating so its worth getting all the
feedback you can to help you through it. Again you configure log4net by adding
to your applications’s configuration file.
<configSections>
<section name=”log4net”
type=”log4net.Config.Log4NetConfigurationSectionHandler,log4net”
/>
</configSections>
<log4net>
<appender name=”ConsoleAppender”
type=”log4net.Appender.ConsoleAppender,
log4net”>
<layout type=”log4net.Layout.PatternLayout,
log4net”>
<param name=”ConversionPattern”
value=”%m” />
</layout>
</appender>
<root>
<priority value=”WARN”
/>
<appender-ref ref=”ConsoleAppender”
/>
</root>
</log4net>
Adding the following line to the application means that you
do not need to re-start the application to make configuration changes:
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
We must add a reference to the library log4net.dll (it is
available with the binaries of NHibernate).
We call log4net.Config.XmlConfigurator.Configure() before
starting to configure NHibernate. This call activates log4net.
log4net.Config.XmlConfigurator.Configure();
Next Time
We will look at how we map entities