There are several key components to an NHibernate application, as shown in this diagram:
On startup, an NHibernate application builds a Configuration
object. In this recipe, we build the configuration from settings in the hibernate.cfg.xml
file. The Configuration
object is responsible for loading mappings, investigating the object model for additional information, building the mapping metadata, and finally building a session factory. Building the session factory is a rather resource intensive operation, and is normally only done once, when the application starts up.
A session represents a Unit of
Work in the application. Martin Fowler defines a Unit of Work as something that "maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems". An NHibernate session tracks changes to entities and writes those changes back to the database all at once. In NHibernate, this process of waiting to write to the database is called transactional write-behind. In addition, the session is the entry point to much of the NHibernate API. More information about the Unit of Work pattern is available at http://martinfowler.com/eaaCatalog/unitOfWork.html and in Fowler's book, Patterns of Enterprise Application Architecture. A session factory is responsible for creating sessions.
The session acts as an intermediary between our application and several key NHibernate components. A typical application will not interact with these components directly, but understanding them is critical to understanding NHibernate. Unlike a session factory, building a session is very cheap.
A dialect is used to build correct SQL syntax for a specific RDBMS. For example, in some versions of Microsoft SQL Server, we begin a select statement with SELECT TOP 20
to specify a maximum result set size. Only 20 rows will be returned. Similarly, to perform this operation in SQLite, we append LIMIT 20
to the end of the select
statement. Each dialect provides the necessary SQL syntax string fragments and other information to build correct SQL strings for the chosen RDBMS.
A driver is responsible for building a Batcher, creating IDbConnection
and IDbCommand
objects, and preparing those commands.
A connection provider is simply responsible for opening and closing database connections.
A batcher manages the batch of commands to be sent to the database and the resulting data readers. Currently, only the SqlClientDriver
, OracleDataDriver
, and MySqlDataDriver
support batching. The drivers that don't support batching provide a NonBatchingBatcher
to manage IDbCommands
and IDataReaders
and simulate the existence of a single logical batch of commands.
Many dialects set other NHibernate properties to sensible default values, including, in most cases, the connection.driver_class
. NHibernate includes the following dialects in the NHibernate.Dialect
namespace and drivers in the NHibernate.Driver
namespace: