NHibernate in Action – Book Review

Book on Amazon
All summer I meant to read the book “NHibernate In Action”. I finally got around to it, better late than never I guess. In my opinion this book is aimed at higher level programmers such as lead developers or architects. The book does not contain clear step by step examples of how to get NHibernate running. However it does provide in depth conceptual reasoning why anyone would want to use NHibernate along with reference style examples. If you are trying to learn NHibernate you are better off reading a few online tutorials first and after that read this book so you can understand exactly what NHibernate is doing and how it does it. Below are some book pros & cons, NHibernate links, and chapter summaries.
Pros
- Examples are all in c#
- Shows config examples for NHibernate 1.2.1 and 2
- Promotes proper design patters often references popular pattern books
- Makes note of minor current bugs or missing features that may cause issues or confusion
- Provides suggestions for when to use something other than the default NHibernate settings
- Mentions how NHibernate can use the features of multiple RDMS, not just SQL Server
Cons
- Download and install instructions were vague
- I downloaded NHibernate 2.1.0 QA from SourceForge after finally finding the link on nhforge.org. From there I followed the install notes in the downloaded zip file.
- Examples do not use Generics
- Doesn’t provide a link or even a suggestion to where you can download the NHibernate.Mapping.Attributes library which lets you use features similar to the annotations in Hibernate 3
- I found them here: http://sourceforge.net/projects/nhcontrib/files/NHibernate.Mapping.Attributes/
- Shows attribute and xml mapping examples randomly. In my opinion it would be better if one or the other was used consistently.
- Jumps from definitions to examples. No clear step by step examples
- I would say this book is more of a reference than tutorial
Helpful NHibernate Links
- NHibernate community site
- NHibernate Google Group
- Stackoverflow NHibernate questions and answers
- How to use MySQL with .NET
- Databases supported by NHibernate
- Common exceptions
Chapter 1
- Basic definitions of persistence, sql(sql not sql server) databases, and layered development
- Doesn’t mention the testability benefits of layered development
- Compares persistence layer choices available with .Net
- Makes the case that LINQ and Entity framework will not replace NHibernate
- Definition of ORM
- Addresses the performance concerns of using ORMs
- Author tries to convince people to use ORMs, this part needs a little salesman ship but I guess if someone is open minded enough to read this book then they don’t need much of a sales pitch.
Chapter 2
- Some basoc instructions for how to download and install the NHibernate dll
- con: Could use a little details in this section about how to use the versions that don’t have msi installers yet like the 2.1.0.GA release I downloaded.
- Shows very simple examples of saving and loading an entity
- Then shows you a basic xml mapping document
- o Shows a mapping document for versions 1.2 and 2.
- Quick glance at the NHibernate api and in depth notes on important interfaces
- Very short section on logging with log4net
Chapter 3
- Good section on the benefits of having a transparent persistence layer
- Discusses the anti xml config file movement.
- However doesn’t mention the fact that poorly designed and overly complicated schemas are one reason for the back lash. Also never mentions CoC.
- Discusses using attributes as meta data
- IMHO way more time should have been spent telling the users how to setup/install the mapping dlls needed to use this feature
- Does show many examples of how to use the attributes and what the xml version of the meta data would look like
- This chapter provides information about the hibernate mapping elements and options
- It is a mix between a reference and tutorial.
- Good section on object identity vs equality
- con: Gives an explanation of what primary keys are. Surely anyone reading this book knows already knows what primary keys are.
- Good short explanation of the different types of primary key creation that NHibernate supports
- Long discussion on database and object model design
- table per concrete class
- table per sub class
- table per class hierarchy
Chapter 4
- Explains object identity scope. probably a little high level for low level developers
- Explains different options for Equals and HashCode implementations
- Automatic dirty checking
- Changing an object in an ISession and committing will result in those changes being automatically reflected in the database
- Clearly denotes the different cascading persistence options
- Details the different object retrieval options
- Retrieving by identifier
- HQL
- NHibernate Criteria API
- Native SQL queries
- In depth discussion of fetching strategies and how to implement each one
- Short section on batching and how it can speed up queries for selecting collections
- Provides common sense ideas for analyzing NHibernate’s performance
Chapter 5
- Background on database transactions, unit of work and conversations
- Excellent section on transaction isolation
- Background on ORM caching
Chapter 6
- Starts with more definitions and comparisons of entities and value types
- Nice chart showing how NHibernate mapping types relate to .Net types
- Give in depth example of creating a custom mapping type
- Nice tips on controlling collection sorting with mapping settings
Book Review: xUnit Test Patterns
Well, as I related in a post on my personal blog before this shared blog came into being, I was going to read a book every two weeks and give a review of it. I should have said that I’d read 200-300 pages per week instead. My latest book is 800+ pages, and it took me three weeks, even when I skimmed several pieces of it. It was, however, an outstanding book.
If you write software, this book is an absolute must-read. If you’ve never written an automated test, it will convince you why you should. If you’re test-infected, it will give you advice and principles to follow that guide you toward more effective testing and, ultimately, more effective software. For anyone in between, this book has something for you, too. It’s written in a language-agnostic way and has advice applicable to testing with any of the “xUnit” family: any test framework that works along the same lines as Java’s JUnit.
xUnit Test Patterns
Refactoring Test Code
by Gerard Meszaros
As its name suggests, it’s a patterns book, which means that Mike would like it because a large part of it is a catalog of various test-related patterns that the author has collected. Another chunk of the book is taken up by a catalog of test smells. This still leaves plenty of room, though, for Meszaros to provide a thorough introduction to software testing–primarily unit testing, but with plenty of consideration for other test scopes as well–and to give a detailed overview of best practices in testing.
Part One of the book is the narrative, non-catalog part and could be a book all by itself. It covers a lot of theoretical ground with topics like goals of automated testing, guiding principles to consider when writing tests, and various philosophies of testing along with their pros and cons. On the more “practical application” front, there’s a basic introduction to the internal workings of the xUnit family frameworks, which is foundational knowledge for many patterns, and a ton of practical advice revolving around real-world examples of difficult testing situations and methods of dealing with them. You could read just this part of the book–under 200 pages–and come away a better developer for it.
Part Two is the catalog of test smells. Each smell is the formalization of a testing problem that was discussed in Part One. A statement of the problem, its symptoms and possible causes, and various suggested solutions are all collected into a neat, tidy package for easy access. The smells cover a wide variety of things from the seemingly trivial difficult-to-read tests to major systemic problems like unreliable test suites due to sporadic test failures.
Part Three is the pattern catalog, where the solutions to aforementioned problems and best practices are formalized. Each pattern has a brief summary up front, a description of how and when to use it appropriately, examples of how the pattern looks in code (in various languages), and examples of how to refactor problem code to solve the problem effectively with the pattern. The initial summary is highly useful in that you can read through the summaries of all 60 or so of the patterns in a very short time and have a feel for which ones you should look into more deeply for a particular situation.
I have to say one more time that you must read this book! It pulls patterns, practices, and more from many other sources and organizes them all in a well-written, easy-to-read reference that will provide a strong foundation for testing efforts in any xUnit framework. Beyond that, I’ve yet to mention the author’s efforts to establish a common vocabulary of test patterns by assembling them all in one place with a strict system of names. While this may seem trivial in comparison to the content of the patterns, the lack of such a vocabulary can lead to real difficulties in communication when four people use a name like “Test Stub” in four very different ways. Learn a better way.
Get this book. Read it. Use it. Live it.
Configuring NHibernate in a Multiple Project Layout
I recently had to setup NHibernate in a multiple project c#, asp.net MVC solution. Since most of the tutorials and books only show a basic single project layout I thought I would post an example of how to configure NHiberate with a multi-project solution.
The main problem I had was that my model objects or entity objects were in a separate project than my database access code which contained the .hbm.xml mapping files. When I tried to configure NHibernate with the basic examples I was getting an “NHibernate.MappingException : No persister for: YourClass” exception. I was still getting that exception even after changing the .hbm.xml files to be an “Embedded Resource”. I finally figured out that my .hbm.xml files needed to reference the ModelLayer assebmly and my NHibernate.Cfg.Configuration.AddAssembly() needed to reference the DataAccessLayer assebmly. See screen shots and code examples below for more details.
Solution layout
- DataAccessLayer
- Duh. Database code
- References
- ModelLayer
- ModelLayer
- Model objects
- MvcAgain (web layer)
- ASP.Net project
- References
- ModelLayer
- ServiceLayer
- ServiceLayer
- Business logic
- Reusable logic
- References
- ModelLayer
- DataAccessLayer
Model objects Car.cs and CarLot.cs
using System.ComponentModel.DataAnnotations;
namespace MvcAgain.Models {
public class Car {
[Required]
public virtual int Id {get; set;}
[StringLength(35), Required]
public virtual string Manufacturer {get; set;}
[StringLength(35), Required]
public virtual string Model {get; set;}
public virtual CarLot Lot {get; set;}
}
}//end of Car.cs
using Iesi.Collections;
using System.ComponentModel.DataAnnotations;
namespace MvcAgain.Models {
public class CarLot {
[Required]
public virtual int Id { get; protected set; }
[StringLength(35), Required]
public virtual string Name { get; protected set; }
public virtual ISet Cars { get; protected set; }
}
}//end of CarLot.cs
Car.hbm.xml and CarLot.hbm.xml
These .hbm.xml files are in the DataAccessLayer project, but they reference the ModelLayer assembly.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="ModelLayer"
namespace="MvcAgain.Models">
<class name="MvcAgain.Models.Car" lazy="false" table="cars">
<id name="Id">
<generator class="native"/>
</id>
<property name="Model"/>
<property name="Manufacturer"/>
<many-to-one name="Lot" class="CarLot" column="lotid" not-null="true">
</many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="ModelLayer"
namespace="MvcAgain.Models">
<class name="MvcAgain.Models.CarLot" lazy="false" table="carlots">
<id name="Id">
<generator class="native"/>
</id>
<property name="Name"/>
<set name="Cars" inverse="true">
<key column="lotid"/>
<one-to-many class="Car"/>
</set>
</class>
</hibernate-mapping>
NHibernateSessionFactory.cs (NHibernate configuration code)
using NHibernate.Cfg;
using NHibernate;
namespace MvcAgain.DataAccessLayer {
public class NHibernateSessionFactory {
private static ISessionFactory sessionFactory = null;
private static ISessionFactory SessionFactory {
get {
if(sessionFactory == null) {
Configuration configuration = new Configuration();
configuration.Configure();
//note: you must use the name of the assembly
//that contains the .hbm.xml mapping files.
//For this example NHibernate will load all .hbm.xml files it
//finds in the DataAccessLayer assembly
configuration.AddAssembly("DataAccessLayer");
sessionFactory = configuration.BuildSessionFactory();
}
return sessionFactory;
}
}
public static ISession OpenSession() {
return SessionFactory.OpenSession();
}
}//end of class
}//end of namespace
ModelLayer assembly name in the properties pane.

