You are currently browsing the category archive for the ‘NHibernate’ category.
First of all, Steve Strong made a Christmas gift to community by presenting a new Linq implementation for NHibernate, which is now incorporated in the trunk. Kudos for a such great work!
Another valuable addition to NHibernate is the QueryOver<T> API that wrapped ICriteria API and made it easier to use. Thanks to Richard Brown.
Both features are not crucial for the success of NHibernate, but they are very nice improvements that will attract new users and will keep the old ones. It’s easier to advocate for NHibernate when you can point not only at his advanced features. The hype around Linq makes difference when features are compared. Having a provider for NHibernate will be a strong decision argument.
I hope that soon after New Year’s holidays I’ll try to switch to NHibernate 3.0. If migration of our project will be painless and all tests will still green, I think we’ll run with the trunk. It’s the least we can do to help make this project better.
“why is this a problem?” may ask you…
Let’s review the ways that NHibernate lets you register your own event listeners. You can do it in configuration file:
<listener class=”NHTest.Listeners.CustomSaveEventListener, NHTest” type=”save” />
… or in code:
Configuration cfg = new Configuration();
cfg.EventListeners.SaveEventListeners =
new ISaveOrUpdateEventListener[] {new CustomSaveEventListener() };
Nice, so far…
It’s not if you want to add a listener, not to replace them. Both registrations are just replacing default event listeners with your own implementations. Very often it’s not want you want!
In our case, we want default listeners do the job and just add few our own listeners to run the business. No problem, let’s code:
var listeners = configuration.EventListeners; listeners.SaveEventListeners = new List<ISaveOrUpdateEventListener>(listeners.SaveEventListeners) {new CustomSaveEventListener()} .ToArray();
Since I wrote that code some day I hated it. Too verbose, too obscure, hard to read & understand. But event registration infrastructure doesn’t offer an easy and simple way to add a listener. Few times I tried to come with a nice solution for that, even tried to modify NH’s code.
Today, I’ve done it:
configuration.AddListener(el => el.SaveEventListeners, new CustomSaveEventListener());
Some expression’s magic and we end up with a very clean & readable code.
Implementation:
public static class NHibernateConfigurationExtensions { public static void AddListener<TListener>( this Configuration configuration, Expression<Func<EventListeners, TListener[]>> expression, TListener listenerImpl) { var propertyInfo = ReflectionHelper.GetProperty(expression); var existentListeners = (TListener[]) propertyInfo.GetValue(configuration.EventListeners, null); var newListeners = new List<TListener>(existentListeners) { listenerImpl }.ToArray(); propertyInfo.SetValue(configuration.EventListeners, newListeners, null); } public static void AddListeners<TListener>( this Configuration configuration, Expression<Func<EventListeners, TListener[]>> expression, IEnumerable<TListener> listeners) { foreach (var listener in listeners) { configuration.AddListener(expression, listener); } } }
Have a nice day...
Ayende is running a series of posts detailing and explaining how NHibernate maps entity classes to database. Posts include XML mappings, code and SQL queries generated when saving or querying the database so that you have everything to understand what NHibernate do to persist your data. The series is a nice addition to NHibernate Reference Documentation.
NHibernate Mapping:
- Properties <property/>
- Components <component/>
- Many to one relationships <many-to-one/>
- Inheritance
- Dynamic components <dynamic-component/>
- Collections <set/>
- Concurrency
- Database objects <database-object/>
- Named queries <query/> & <sql-query/>
- One to one relations <one-to-one/>
- Joined classes <join/>
- Any type mappings <any/>
- Many to any relationships <many-to-any/>
It was a nice reading. I’ve refreshed few things in my memory and learned few new tricks.
This post will be updated as new chunks will be published (I hope it will) by Ayende.
Very often you’re going over a description of some function or new feature and just notice in your mind, “nice feature” without seeing a real application for it. Later, you’re coming with scenario where the trick you’ve read days ago will fit perfectly.
That was the case when I’ve seen earlier in Tuna Toksoz‘s weblog a description of “hbm2ddl.auto” property. Few days ago, I’ve put it to work in a way that makes me feel better. By the way, the particular reason that made me happy was that I’ve deleted a lot of repetitive code from our code base.
How you can use hbm2ddl.auto property in unit tests
Our integration tests are run over a real database. For each test we’re re-creating the database, so that each test will be ran in separation and without interfering with results of previous tests. Also, things are a bit complicated since we’re working with few databases at the same time, each with his own schema. Before, each test had to use SchemaExport class that exported the database schema built from NHibernate configuration on the way deleting your old database/schema/data. So, each integration test class had same method to call. Redundant and repetitive. Yes, you can make a base class that will do that, but you have to inherit then all tests from that class.
How it works now: in session configuration (usually in app.config for integration test project) you put:
<property name=”hbm2ddl.auto”>create</property>
… and you’re set. Each time your code will build a new SessionFactory, NHibernate will call:
new SchemaExport(cfg).Create(false, true);
This way, before the SessionFactory will be built, your database will be refreshed with a new schema and tests will run in a clean database.
One line of code instead of tens or hundreds. Isn’t that a good trick?!
A word of warning – don’t let this code escape to your production code. It may be dangerous… But, you know that, we’re running with scissors…
As always, business requirement went over existing code base to ask for a minor change that wasn’t compatible with our existing infrastructure: all surrogate keys are unique identifiers (Guid) and all infrastructure was built around that. The business people asked to add to an existing domain entity a natural key – integer identity number (auto increment field), to serve as a reference number.
We had two choices:
- to generate the identity from business code
- to let database manage it for us.
The second approach it preferable for us because it’s the database’s job to generate the keys.
Out of the box NHibernate doesn’t support such a thing. Answers to my question in NHibernate Users discussion group led to the next solution.
Given the class:
public class Entity { public int Id { get; set; } public int Id2 { get; set; } }
First “Id” is the primary key, the second is the key that we want to map to identity column. To have that done we should do two things:
- Map “Id2″ property as “generated”
- Use “database-object” to drop the column generated by NHibernate & create new one, with IDENTITY set on.
The complete mapping:
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="NHibernate.Playground" assembly="NHibernate.Playground" default-lazy="false" xmlns="urn:nhibernate-mapping-2.2"> <class name="Entity"> <id name="Id"> <generator class="increment" /> </id> <property name="Id2" type="int" generated="always" insert="false" /> </class> <database-object> <create> ALTER TABLE Entity DROP COLUMN Id2 ALTER TABLE Entity ADD Id2 INT IDENTITY </create> <drop> ALTER TABLE Entity DROP COLUMN Id2 </drop> </database-object> </hibernate-mapping>
I like the flexibility offered by NHibernate. Even if you don’t have required feature, you can always use naked ADO.NET or raw SQL.
Generally, the goal of integration tests is to verify that different application parts are glued well together and interacts as expected. Thus, they are a bit different thing from unit tests that tends to test how a small, separate part is acting. Below are two tests that I can’t classify to be pure integration tests because they touch a sensible part of application/infrastructure configuration like Windsor’s configuration files and NHibernate’s mappings. These simple tests can save a lot of time at very initial development stage when application bits are changed frequently and later, as a guarantee that you’ve not broken something in a recent refactoring.
Can_resolve_all_services_in_container()
Bill Simser wrote some time ago about the first test to be written when using Castle’s Windsor Container. It’s a real gem that let’s you verify if any of services registered in container can be resolved (have all required dependencies). Here is it, a bit improved for skipping verification for generic types, since, at that moment, we don’t know the generic argument for type to be constructed:
[Test] public void Can_resolve_all_services_in_container() { var container = new WindsorContainer("container.xml"); foreach (IHandler handler in container.Kernel.GetAssignableHandlers(typeof(object))) { if (handler.ComponentModel.Service.IsGenericType) continue; container.Resolve(handler.ComponentModel.Service); } }
Can_compile_NHibernate_mapping_configuration()
This test was sitting for a long time in our codebase, but I’ve seen it recently in this post of David Larebee. I wrote it in times when writing our first mappings and the only one way to verify if you don’t have any faults was to write one of CRUD operations and run the test. But that’s a long process. Shorter response cycle is always better. Here it is:
[Test] public void Can_compile_NHibernate_mapping_configuration() { ISessionFactory factory = new Configuration() .Configure() .AddAssembly("MyApp.MyDomainAssembly") .BuildSessionFactory(); Assert.IsNotNull(factory); }
This test suppose that you have HNibernate configuration in your app.config and tries to register all mappings from given assembly file.

