Notebook NHibernate

Alex van Buitenen

This is not a NHibernate tutorial or Quick Reference.
It is just my personal notebook for NHibernate.

Which version of NHibernate to use for which version of Viasual Studio/.NET Framework?
see http://en.wikipedia.org/wiki/NHibernate

"NHibernate 3.0 released
Yesterday, Fabio announced the release of NHibernate 3.0 General Availability. Go get it!
The previous official release of NHibernate was version 2.1.2, just over 1 year ago.
Since then, the team has made a ton of improvements and bug fixes.
Most importantly, NHibernate now targets .NET 3.5, allowing us to use lambda expressions and LINQ.
This has led to an explosion of new ways to configure and query."

Bron: http://nhforge.org/blogs/nhibernate/archive/2010/12/05/nhibernate-3-0-released.aspx

downloads at http://sourceforge.net/projects/nhibernate/files/NHibernate/

What does "GA" mean in the dowload versions?
General availability (GA) General availability (GA) is the point where all necessary commercialization activities have been completed and the software has been made available to the general market either via the web or physical media.
Bron: http://en.wikipedia.org/wiki/Software_release_life_cycle

From NHibernate in action

1.2.7 Updating an Employee

Notice how NHibernate detected the modification to the name and manager properties of the first Employee
(Fred) and automatically updated the database. We’ve taken advantage of a NHibernate feature called
automatic dirty checking: This feature saves us the effort of explicitly asking NHibernate to update the
database when we modify the state of an object. Similarly, you can see that the new Employee (Bill) was
saved when it was associated with the first Employee. This feature is called cascading save: It saves us the
effort of explicitly making the new object persistent by calling Save()
, as long as it’s reachable by an already
persistent object
(Bill). Also notice that the ordering of the SQL statements isn’t the same as the order in which
we set fields of the object. NHibernate uses a sophisticated algorithm to determine an efficient ordering that
avoids database foreign key constraint violations but is still sufficiently predictable to the user. This feature is
called transactional write-behind.

2.2.1 The core interfaces:

An instance of ISession is lightweight and is
inexpensive to create and destroy. This is important because your application will need to create and destroy
sessions all the time, perhaps on every ASP.NET page request. NHibernate sessions are not thread safe and
should by design be used by only one thread at a time.

2.4.2 Logging

NHibernate (and many other ORM implementations) defers the execution of SQL statements. An INSERT statement isn’t usually executed when the application calls ISession.Save(); an UPDATE isn’t immediately issued when the application calls Item.AddBid(). Instead, the SQL statements are usually issued at the end of a transaction. This behavior is called write-behind, as we mentioned earlier.

4.2 The persistence manager

creation of an ISessionFactory is extremely expensive.

7.3.3 Using aliases with joins

We’ve already discussed the role of the where clause in expressing restriction. Often, you’ll need to
apply restriction criteria to multiple associated classes (joined tables). If we want to do this using an
HQL from clause join, we need to assign an alias to the joined class:
from Item item
join item.Bids bid
where item.Description like '%part%'
and bid.Amount > 100
This query assigns the alias item to the class Item and the alias bid to the joined Item’s bids. We then
use both aliases to express our restriction criteria in the where clause.

From NHibernate Reference

9.7.1. Flushing the Session

If you happen to be using the ITransaction API, you don't need to worry about this step. It will be performed implicitly when the transaction is committed. Otherwise you should call Session.Flush() to ensure that all changes are synchronized with the database.

9.7.3. Closing the ISession

A call to ISession.Close() marks the end of a session. The main implication of Close() is that the ADO.NET connection will be relinquished by the session.

From NHibernate in action

Paging the result

Pagination is a commonly used technique, and you’ve probably seen it in action several times. For
example, an eCommerce web site may display lists of products over a number of pages, each showing
only 10 or 20 products at a time. Typically, users navigate to next or previous pages by clicking
appropriate links in the page. When writing data access code for this scenario, the developers needed
to work out how to show the correct page of records at any given time – and that’s what pagination is
all about.
In NHibernate, both the IQuery and ICriteria interfaces make pagination simple, as demonstrated
below:
IQuery query =
session.CreateQuery("from User u order by u.Name asc");
query.SetFirstResult(0);
query.SetMaxResults(10);
The call to SetMaxResults(10) limits the query result set to the first 10 objects selected by the
database. What if we wanted to get some results for the next page?
ICriteria crit = session.CreateCriteria(typeof(User));
crit.AddOrder( Order.Asc("Name") );
crit.SetFirstResult(10);
crit.SetMaxResults(10);
IList<User> results = crit.List<User>();
Starting from the 10th object, we retrieve the next 10 objects. Note that there is no standard way to
express pagination in SQL, and each database vendor often provides a different syntax and approach.
Fortunately, NHibernate knows the tricks for each vendor, so paging is very easily done regardless of
your your particular database.

See also http://stackoverflow.com/questions/1651723/nhibernate-paging-with-sql-server

 

Problem: NHibernate says "multi-part identifier "Parent.Child" could not be bound".

Have read a parent object with NHibernate.
parent has many-to-one relationship with child.
When the parent object is read, the child object is filled correct.

NHibernate mapping as follows:

<class name="Parent" table="tbl_Parent" lazy="false" >
  <id name="ParentId">
    <column name="ParentId" />
    <generator class="native" />
  </id>
  <many-to-one name="Child" column="ChildId" lazy="false" class="Child" />
...
</class>

C# code as follows:

string query = "from Parent";
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();

So far, so good.

Now I want to include a field from the child in the selection query of the parent.
string query = "from Parent where Child.Field = 1";
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();
Error: multi-part identifier "Parent.Child" could not be bound

Solved by:

string query = "Select Parent from Parent Parent join Parent.Child Child";
query += " WHERE Child.Field = 1"
IQuery q = Session.CreateQuery(query);
return q.List<Parent>();

UniqueResult

"by using UniqueResult I tell NHibernate that I expect only one record to return. If more than one record is returned by the HQL query then an exception is raised."
Source: http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/04/01/your-first-nhibernate-based-application.aspx