December 2009

Volume 24 Number 12

Data Access - Building a Desktop To-Do Application with NHibernate

By Oren Eini | December 2009

NHibernate is an Object Relational Mapper (OR/M), tasked with making it as easy to work with a database as it is to work with in-memory objects. It is one of the most popular OR/M frameworks for Microsoft .NET Framework development. But most users of NHibernate are doing so in the context of Web applications, so there is relatively little information about building NHibernate applications on the desktop.

When using NHibernate in a Web application, I tend to use the session-per-request style, which has a lot of implications that are easy to miss. I don’t worry about the session maintaining a reference to the loaded entities, because I expect that the session will go away shortly. I don’t have to worry about error handling (much), as I can just abort the current request and its associated session if an error occurs.

The lifetime of the session is well defined. I don’t need to update other sessions about any changes that I made. I don’t need to worry about holding a long transaction in the database, or even holding a connection open for a long time, because they are only alive for the duration of a single request.

As you can imagine, those are concerns in a desktop application. Just to be clear about it, I am talking about an application talking to a database directly. An application that uses some sort of remote services is using NHibernate on the remote server, under the per-request scenario, and is not the focus of this article. This article does not cover occasionally connected scenarios, although much of the discussion here would apply to those scenarios.

Building an NHibernate-based desktop application isn’t much different than building a desktop application using any other persistence technology. Many of the challenges that I intend to outline in this article are shared between all data-access technologies:

  • Managing the scope of units of work.
  • Reducing duration of opened database connections.
  • Propagating entity changes to all parts of the application.
  • Supporting two-way data binding.
  • Reducing startup times.
  • Avoiding blocking the UI thread while accessing the database.
  • Handling and resolving concurrency conflicts.

While the solutions that I give are dealing exclusively with NHibernate, at least the majority of them are also applicable to other data-access technologies. One such challenge, shared by all data-access technologies that I am aware of, is how to manage the scope of the application’s unit of work—or, in NHibernate’s terms, the session lifetime.

Managing Sessions

A common bad practice with NHibernate desktop applications is to have a single global session for the entire application. It is a problem for many reasons, but three of them are most important. Because a session keeps a reference to everything that it loaded, the user working on the application is going to load an entity, work with it a bit, and then forget about it. But because the single global session is maintaining a reference to it, the entity is never released. In essence, you have a memory leak in your application.

Then there is the problem of error handling. If you get an exception (such as StaleObjectStateException, because of concurrency conflict), your session and its loaded entities are toast, because with NHibernate, an exception thrown from a session moves that session into an undefined state. You can no longer use that session or any loaded entities. If you have only a single global session, it means that you probably need to restart the application, which is probably not a good idea.

Finally, there’s the issue of transaction and connection handling. While opening a session isn’t akin to opening a database connection, using a single session means that you are far more likely to hold transactions and connection for longer than you should.

Another equally bad and, unfortunately, almost as common practice with NHibernate is micromanaging the session. A typical example is code like this:

public void Save(ToDoAction action) {
  using(var session = sessionFactory.OpenSession())
  using(var tx = session.BeginTransaction()) {
    session.SaveOrUpdate(action);

    tx.Commit();
  }
}

The problem with this type of code is that it removes a lot of the advantages that you gain in using NHibernate. NHibernate is doing quite a bit of work to handle change management and transparent persistence for you. Micromanaging the session cuts off NHibernate’s ability to do that and moves the onus of doing that work to you. And that is even without mentioning the problems it causes with lazy loading down the line. In just about any system where I have seen such an approach attempted, the developers had to work harder to resolve those problems.

A session should not be held open for too long, but it should also not be held open for too short a time to make use of NHibernate’s capabilities. Generally, try to match the session lifetime to the actual action that is being performed by the system. 

The recommended practice for desktop applications is to use a session per form, so that each form in the application has its own session. Each form usually represents a distinct piece of work that the user would like to perform, so matching session lifetime to the form lifetime works quite well in practice. The added benefit is that you no longer have a problem with memory leaks, because when you close a form in the application, you also dispose of the session. This would make all the entities that were loaded by the session eligible for reclamation by the garbage collector (GC).

There are additional reasons for preferring a single session per form. You can take advantage of NHibernate’s change tracking, so it will flush all changes to the database when you commit the transaction. It also creates an isolation barrier between the different forms, so you can commit changes to a single entity without worrying about changes to other entities that are shown on other forms.

While this style of managing the session lifetime is described as a session per form, in practice you usually manage the session per presenter. The code in Figure 1 is taken from the presenter base class.

Figure 1 Presenter Session Management

protected ISession Session {
  get {
    if (session == null)
      session = sessionFactory.OpenSession();
    return session;
  }
}

protected IStatelessSession StatelessSession {
  get {
    if (statelessSession == null)
      statelessSession = sessionFactory.OpenStatelessSession();
    return statelessSession;
  }
}

public virtual void Dispose() {
  if (session != null)
    session.Dispose();
  if (statelessSession != null)
    statelessSession.Dispose();
}

As you can see, I lazily open a session (or a stateless session) and keep it open until I dispose of the presenter. This style matches quite nicely to the lifetime of the form itself and allows me to associate a separate session with each presenter.

Maintaining Connections

In the presenters, you don’t have to worry about opening or closing the session. The first time that you access a session, it’s opened for you, and it will dispose itself properly as well. But what about the database connection associated with the session? Are you holding a database connection open for as long as the user is viewing the form?

Most databases dislike having to hold a transaction open for extended periods of time. It usually results in causing errors or deadlocks down the line. Opened connections can cause similar problems, because a database can only accept so many connections before it runs out of resources to handle the connection.

To maximize performance of your database server, you should keep transaction lifespan to a minimum and close connections as soon as possible, relying on connection pooling to ensure fast response times when you open a new connection.

With NHibernate, the situation is much the same, except that NHibernate contains several features that are there to explicitly make things easier for you. The NHibernate session doesn’t have a one-to-one association with a database connection. Instead, NHibernate manages the database connection internally, opening and closing it as needed. This means you don’t have to maintain some sort of state in the application to disconnect and reconnect to the database as needed. By default, NHibernate will minimize to the maximum extent the duration in which a connection is open.

You do need to worry about making transactions as small as possible. In particular, one of the things that you don’t want is to hold a transaction open for the lifetime of the form. This will force NHibernate to keep the connection open for the duration of the transaction. And because the lifetime of a form is measured in human response times, it’s more than likely that you would end up holding up a transaction and connection for longer periods than is really healthy.

What you will usually do is open separate transactions for each operation that you make. Let’s look at a form mockup that shows a simple to-do list, my sample application of choice (see Figure 2). The code for handling this form is quite simple, as you can see in Figure 3.

A To-Do List Application

Figure 2 A To-Do List Application

Figure 3 Creating the To-Do Form

public void OnLoaded() {
  LoadPage(0);
}

public void OnMoveNext() {
  LoadPage(CurrentPage + 1);
}

public void OnMovePrev() {
  LoadPage(CurrentPage - 1);
}

private void LoadPage(int page) {
  using (var tx = StatelessSession.BeginTransaction()) {
    var actions = StatelessSession.CreateCriteria<ToDoAction>()
      .SetFirstResult(page * PageSize)
      .SetMaxResults(PageSize)
      .List<ToDoAction>();

    var total = StatelessSession.CreateCriteria<ToDoAction>()
      .SetProjection(Projections.RowCount())
      .UniqueResult<int>();

    this.NumberOfPages.Value = total / PageSize + 
               (total % PageSize == 0 ? 0 : 1);
    this.Model = new Model {
      Actions = new ObservableCollection<ToDoAction>(actions),
      NumberOfPages = NumberOfPages,
      CurrentPage = CurrentPage + 1
    };
    this.CurrentPage.Value = page;

    tx.Commit();
  }
}

I have three operations: loading the form for the first time, showing the first page, and paging back and forth through the records.

On each operation, I begin and commit a separate transaction. That way I don’t consume any resources on the database and don’t have to worry about long transactions. NHibernate will automatically open a connection to the database when I begin a new transaction and close it once the transaction is completed.

Stateless Sessions

There is another small subtlety that I should note: I’m not using an ISession. Rather, I’m using IStatelessSession in its place to load the data. Stateless sessions are typically used in bulk data manipulation, but in this case I’m making use of a stateless session to resolve memory consumption issues.

A stateless session is, well, stateless. Unlike a normal session, it doesn’t maintain a reference to the entities that it loads. As such, it’s perfectly suited to loading entities for display-only purposes. For that type of task, you generally load the entities from the database, throw them on the form and forget about them. A stateless session is just what you need in this case.

But stateless sessions come with a set of limitations. Chief among them in this case is that stateless sessions do not support lazy loading, do not involve themselves in the usual NHibernate event mode and do not make use of NHibernate’s caching features.

For those reasons, I generally use them for simple queries where I just want to show the user the information without doing anything complicated. In cases where I want to show an entity for editing, I could still make use of a stateless session, but I tend to avoid that in favor of a normal session.

In the main application form, I strive to make all the data display-only, and try to make use of stateless sessions alone. The main form lives for as long as the application is open and a stateful session is going to be a problem, not only because it will maintain a reference to the entities that it loaded, but because it’s likely to cause problems if the session throws an exception.

NHibernate considers a session that threw an exception to be in an undefined state (only Dispose has a defined behavior in this case). You would need to replace the session, and because entities loaded by a stateful session maintain a reference to it, you would need to clear all the entities that were loaded by the now-defunct session. It’s so much simpler to use a stateless session in this circumstance.

Entities loaded by stateless sessions do not care for the state of the session, and recovering from an error in a stateless session is as simple as closing the current stateless session and opening a new one.

Manipulating Data

Figure 4 shows the edit screen mockup. What challenges do you face when you need to edit entities?

Editing Entities

Figure 4 Editing Entities

Well, you actually have two separate challenges here. First, you want to be able to make use of NHibernate’s change tracking, so you can display an entity (or an entity object graph) and have NHibernate just persist it when you’re finished. Second, once you save an entity, you want to ensure that every form that also displays this entity is updated with the new values.

The first item of business is actually fairly easy to handle. All you need to do is make use of the session associated with the form, and that’s it. Figure 5 shows the code driving this screen.

Figure 5 Editing an Entity in the Session

public void Initialize(long id) {
  ToDoAction action;
  using (var tx = Session.BeginTransaction()) {
    action = Session.Get<ToDoAction>(id);
    tx.Commit();
  }

  if(action == null)
    throw new InvalidOperationException(
      "Action " + id + " does not exists");

  this.Model = new Model {
    Action = action
  };
}

public void OnSave() {
  using (var tx = Session.BeginTransaction()) {
    // this isn't strictly necessary, NHibernate will 
    // automatically do it for us, but it make things
    // more explicit
    Session.Update(Model.Action);

    tx.Commit();
  }

  EventPublisher.Publish(new ActionUpdated {
    Id = Model.Action.Id
  }, this);

  View.Close();
}

You get the entity from the database in the Initialize(id) method, and you update it in the OnSave method. Notice that you do so in two separate transactions, instead of keeping a transaction alive for a long period of time. There’s also this strange EventPublisher call. What’s that all about?

EventPublisher is here in order to deal with another challenge: when each form has its session, then each form has different 
instances of the entities you work with. On the face of it, that looks like a waste. Why should you load the same action several times?

In actuality, having this separation between the forms will simplify the application considerably. Consider what would happen if you shared the entity instances across the board. In that situation, you would find yourself with a problem in any conceivable edit scenario. 
Consider what would happen if you were to display an entity in two forms that allow editing that entity. That may be an editable grid and a detailed edit form, for example. If you make a change to the entity in the grid, open the detailed edit form and then save it, what would happen to the change you made on the editable grid?

If you employ a single entity instance throughout the application, then it’s likely that saving the details form would also cause you to save the changes made using the grid. That’s likely not something that you would want to do. Sharing an entity instance also makes it much more difficult to do things like cancel an edit form and have all the unsaved changes go away.

Those problems simply do not exist when you use an entity instance per form, which is a good thing, as this is more or less mandatory when you use a session per form approach.

Publishing Events

But I haven’t fully explained the purpose of the EventPublisher yet. It’s actually fairly simple. Instead of having a single instance of the entity in the application, you may have many, but the user would still like to see the entity (once properly saved) updated on all the forms that show that entity.

In my example I do so explicitly. Whenever I save an entity, I publish an event saying that I did so, and on which entity. This isn’t a standard .NET event. A .NET event requires a class to subscribe to it directly. That doesn’t actually work for this type of notification because it would require each form to register to events in all other forms. Just trying to manage that would be a nightmare.

The EventPublisher is a publish-subscribe mechanism that I use to decouple a publisher from its subscriber. The only commonality between them is the EventPublisher class. I use the event type (ActionUpdated in Figure 5) to decide who to tell about the event.

Let’s look at the other side of that now. When I update a to-do action, I would like to show the updated values in the main form, which shows a grid of to-do actions. Here is the relevant code from that form presenter:

public Presenter() {
  EventPublisher.Register<ActionUpdated>(
    RefreshCurrentPage);
}

private void RefreshCurrentPage(
  ActionUpdated actionUpdated) {
  LoadPage(CurrentPage);
}

On startup, I register the method RefreshCurrentPage to the ActionUpdated event. Now, whenever that event is raised, I will simply refresh the current page by calling LoadPage, which you are already familiar with.

This is actually a fairly lazy implementation. I don’t care if the current page is showing the edited entity; I just refresh it anyway. A more complex (and efficient) implementation would only refresh the grid data if the updated entity is shown on that page.

The main advantage of using the publish-subscribe mechanism in this manner is decoupling the publisher and subscribers. I don’t care in the main form that the edit form publishes the ActionUpdated event. The idea of event publishing and publish-subscribe is a cornerstone in building loosely coupled user interfaces, and is covered extensively in the Composite Application Guidance (msdn.microsoft.com/library/cc707819) from the Microsoft patterns & practices team.

There is another case worth considering: What would happen if you have two edit forms to the same entity open at the same time? How can you get the new values from the database and show them to the user?

The following code is taken from the edit form presenter:

public Presenter() {
  EventPublisher.Register<ActionUpdated>(RefreshAction);
}

private void RefreshAction(ActionUpdated actionUpdated) {
  if(actionUpdated.Id != Model.Action.Id)
    return;
  Session.Refresh(Model.Action);
}

This code registers for the ActionUpdated event, and if it’s the entity that you’re editing, you ask NHibernate to refresh it from the database.

This explicit model of refreshing the entity from the database also gives you the chance to make decisions about what should happen now. Should you update automatically, erasing all the user changes? Should you ask the user? Try to silently merge the changes? Those are all decisions that you now have the chance to deal with in a straightforward manner.

In most cases, however, I find that simply refreshing the entity is quite enough, because you generally do not allow updating of a single entity in parallel (at least not by a single user).

While this entity refresh code will indeed update the values of the entity instance, how are you going to make the UI respond to this change? You have data bound the entity values to the form fields, but you need some way of telling the UI that those values have changed.

The Microsoft .NET Framework provides the INotifyPropertyChanged interface, which most UI frameworks understand and know how to work with. Here’s the INotifyPropertyChanged definition:

public delegate void PropertyChangedEventHandler(
  object sender, PropertyChangedEventArgs e);

public class PropertyChangedEventArgs : EventArgs {
  public PropertyChangedEventArgs(string propertyName);
  public virtual string PropertyName { get; }
}

public interface INotifyPropertyChanged {
  event PropertyChangedEventHandler PropertyChanged;
}

An object that implements this interface should raise the PropertyChanged event with the name of the property that was changed. The UI will subscribe to the PropertyChanged event and whenever a change is raised on a property that’s bound, it will refresh the binding.

Implementing this is quite easy:

public class Action : INotifyPropertyChanged {
  private string title;
  public virtual string Title {
    get { return title; }
    set {
      title = value;
      PropertyChanged(this, 
        new PropertyChangedEventArgs("Title"));
    }
  }

  public event PropertyChangedEventHandler 
    PropertyChanged = delegate { };
}

While simple, it’s fairly repetitive code, and is only required to satisfy UI infrastructure concerns.

Intercepting Entity Creation

I don’t want to have to write code just to get the UI data binding working properly. And as it turns out, I don’t actually need to.

One of the requirements of NHibernate is that you make all properties and methods on your classes virtual. NHibernate requires this to handle lazy loading concerns properly, but you can take advantage of this requirement for other reasons.

One thing you can do is take advantage of the virtual keyword to inject your own behavior into the mix. You do this using a technique called Aspect-Oriented Programming (AOP). In essence, you take a class and add additional behaviors to this class at runtime. The exact mechanism of how you implement this is outside the scope of the article, but it’s encapsulated in the DataBindingFactory class, whose definition is:

public static class DataBindingFactory {
  public static T Create<T>();
  public static object Create(Type type);
}

The entire implementation of the class is about 40 lines, not terribly complex. What it does is take a type and produce an instance of this type that also fully implements the INotifyPropertyChanged contract. In other words, the following test will work:

ToDoAction action = DataBindingFactory.Create<ToDoAction>();
string changedProp = null;
((INotifyPropertyChanged)action).PropertyChanged 
  += (sender, args) => changedProp = args.PropertyName;
action.Title = "new val";
Assert.Equal("Title", changedProp);

Given that, all you have to do now is make use of the DataBindingFactory whenever you create a new class in the presenters. The main advantage that you gain from such a system is that now, if you would like to make use of the NHibernate domain model in a non-presentation context, you can simply not make use of the DataBindingFactory, and you get a domain model completely free from presentation concerns.

There’s still one problem, though. While you can create newinstances of entities using the DataBindingFactory, a lot of the time you will have to deal with instances that were created by NHibernate. Obviously, NHibernate knows nothing about your DataBindingFactory and can’t make use of it. But before you despair, you can make use of one of the most useful extension points with NHibernate, the Interceptor. NHibernate’s Interceptor allows you to take over, in essence, some of the functionalities that NHibernate is performing internally.

One of the functionalities that the Interceptor allows you to take over is creating new instances of entities. Figure 6 shows an Interceptor that creates instances of entities using the DataBindingFactory.

Figure 6 Intercepting Entity Creation

public class DataBindingInterceptor : EmptyInterceptor {
  public ISessionFactory SessionFactory { set; get; }

  public override object Instantiate(string clazz, 
    EntityMode entityMode, object id) {

    if(entityMode == EntityMode.Poco) {
      Type type = Type.GetType(clazz);
      if (type != null) {
        var instance = DataBindingFactory.Create(type);
        SessionFactory.GetClassMetadata(clazz)
          .SetIdentifier(instance, id, entityMode);
        return instance;
      }
    }
    return base.Instantiate(clazz, entityMode, id);
  }

  public override string GetEntityName(object entity) {
    var markerInterface = entity as
      DataBindingFactory.IMarkerInterface;
    if (markerInterface != null)
      return markerInterface.TypeName;
    return base.GetEntityName(entity);
  }
}

You override the Instantiate method and handle the case where we get an entity with a type that you recognize. You then proceed to create an instance of the class and set its identifier property. You also need to teach NHibernate how to understand what type an instance created via DataBindingFactory belongs to, which you do in the GetEntityName method of the intercepter.

The only thing left now is to set up NHibernate with the new Interceptor. The following is taken from the BootStrapper class, responsible for setting up the application:

public static void Initialize() {
  Configuration = LoadConfigurationFromFile();
  if(Configuration == null) {
    Configuration = new Configuration()
      .Configure("hibernate.cfg.xml");
    SaveConfigurationToFile(Configuration);
  }
  var intercepter = new DataBindingIntercepter();
  SessionFactory = Configuration
    .SetInterceptor(intercepter)
    .BuildSessionFactory();
  intercepter.SessionFactory = SessionFactory;
}

For now, ignore the configuration semantics—I will address that in a bit. The important point is that you create the Interceptor, set it on the configuration and build the session factory. The last step is setting the session factory on the Interceptor. It’s a bit awkward, I’ll admit, but that’s the simplest way to get the appropriate session factory into the Interceptor.

Once the Interceptor is wired, every entity instance that NHibernate creates will now support INotifyPropertyChanged notifications without you having to do any work at all. I consider this quite an elegant solution to the problem.

There are a few who would say that choosing such a solution is a problem from a performance perspective over hard coding the implementation. In practice, that turns out to be a false assumption. The tool that I’m using (Castle Dynamic Proxy) to perform this on-the-fly extension of classes has been heavily optimized to ensure optimal performance.

Addressing Performance

Speaking of performance, an additional concern in desktop applications that you do not have in Web applications is startup time. In Web applications it is quite common to decide to favor longer startup times to increase request performance. In desktop applications, you would like to reduce the startup time as much as possible. In fact, a common cheat with desktop application is to simply show a screen shot of the application to the user until the application finishes starting up.

Unfortunately, NHibernate startup time is somewhat long. This is mostly because NHibernate is performing a lot of initialization and checks on startup, so it can perform faster during normal operation. There are two common ways of handling this issue.

The first is to start NHibernate in a background thread. While this means the UI will show up much faster, it also creates a complication 
for the application itself, because you can’t show the user anything from the database until you finish the session factory startup.

The other option is to serialize NHibernate’s Configuration class. A large amount of the cost related to NHibernate startup is related to the cost of validating the information passed to the Configuration class. The Configuration class is a serializable class and therefore you can pay that price only once, after which you can shortcut the cost by loading an already validated instance from persistent storage.

That is the purpose of the LoadConfigurationFromFile and SaveConfigurationToFile, serializing and deserializing NHibernate’s configuration. Using these you only have to create the configuration the first time you start the application. But there’s a small catch you should be aware of: You should invalidate the cached configuration if the entities assembly or the NHibernate configuration file has changed.

The sample code for this article contains a full implementation that‘s aware of this and invalidates the cached file if the entities or the configuration have changed.

There’s another performance issue that you have to deal with. Calling the database is one of the more expensive operations that the application makes. As such, it’s not something that you’d want to do on the application UI thread.

Such duties are often relegated to a background thread, and you can do the same with NHibernate, but keep in mind that the NHibernate session is not thread safe. While you can make use of a session in multiple threads (it has no thread affinity), you must not use a session (or your entities) on multiple threads in parallel. In other words, it’s perfectly fine to use the session in a background thread, but you must serialize access to the session and not allow concurrent access to it. Using the session from multiple threads in parallel will result in undefined behavior; in other words, it should be avoided.

Luckily, there are a few relatively simple measures that you can take in order to ensure that access to the session is serialized. The System.ComponentModel.BackgroundWorker class was explicitly designed to handle these sorts of tasks. It allows you to execute a task on a background thread and notify you when it is completed, taking care of the UI thread synchronization issue, which is so important in desktop applications.

You saw earlier how to manage editing an existing entity, which I did directly on the UI thread. Now, let’s save a new entity on a background thread. The following code is the initialization of the Create New presenter:

private readonly BackgroundWorker saveBackgroundWorker;

public Presenter() {
  saveBackgroundWorker = new BackgroundWorker();
  saveBackgroundWorker.DoWork += 
    (sender, args) => PerformActualSave();
  saveBackgroundWorker.RunWorkerCompleted += 
    (sender, args) => CompleteSave();
  Model = new Model {
    Action = DataBindingFactory.Create<ToDoAction>(),
    AllowEditing = new Observable<bool>(true)
  };
}

The BackgroundWorker is used to perform the actual save process, which was split into two distinct pieces. Aside from that split, it’s very similar to the way I handled it in the edit scenario. Another interesting bit that you need to pay attention to is the AllowEditing property; this property is used to lock the UI in the form when you’re performing a save operation. This way, you can safely use the session in another thread, knowing that there won’t be concurrent access to either the session or any of its entity by that form.

The saving process itself should be pretty familiar to you by now. Let’s look at the OnSave method first:

public void OnSave() {
  Model.AllowEditing.Value = false;
  saveBackgroundWorker.RunWorkerAsync();
}

This method is responsible for disabling editing in the form, then kicking off the background process. In the background, you perform the actual save. The code shouldn’t come as a surprise:

private void PerformActualSave() {
  using(var tx = Session.BeginTransaction()) {
    Model.Action.CreatedAt = DateTime.Now;
    
    Session.Save(Model.Action);
    tx.Commit();
  }
}

When the actual save to the database is completed, the BackgroundWorker will execute the CompleteSave part of the process in the UI thread:

private void CompleteSave() {
  Model.AllowEditing.Value = true;
  EventPublisher.Publish(new ActionUpdated {
    Id = Model.Action.Id
  }, this);

  View.Close();
}

You re-enable the form, publish a notification that an action was updated (causing the relevant screens to update as well), and finally close the form. I suppose that enabling the UI isn’t strictly necessary, but I included it there for completion sake.

Using this technique, you can take advantage of background processing without violating the threading contract on the session instances. As always, threading is a great way to create a more responsive application, but multi-threaded programming is not a task to be approached lightly, so use this technique with care.

Dealing with Concurrency

Concurrency is a complex topic at the best of times, and it isn’t limited to threading alone. Consider the case where you have two users that edit the same entity at the same time. One of them is going to hit the submit button first, saving the changes to the database. The question is, what should happen when the second user hits the save button?

This is called a concurrency conflict, and NHibernate has quite a few ways of detecting such a conflict. The ToDoAction entity has a <version/> field that tells NHibernate that it needs to explicitly perform optimistic concurrency checks. For a full discussion of the concurrency options that NHibernate offers, see my blog post at ayende.com/Blog/archive/2009/04/15/nhibernate-mapping-concurrency.aspx.

Essentially, the concurrency solutions fall into two broad categories:

  • Pessimistic concurrency control, which requires you to hold locks on the database and keep the transaction open for an extended period of time. As I discussed earlier, this is not a good idea in a desktop application.
  • Optimistic concurrency control, which means you can close the database connection during the user’s “think time.” Most of the options NHibernate has to offer are on the optimistic side, allowing several strategies to detect conflicts.

Because pessimistic concurrency control incurs such a heavy performance cost, it’s generally not acceptable. This, in turn, means that you should favor optimistic concurrency control. With optimistic concurrency, you try to save the data normally, but you’re prepared to handle the case where the data was changed by another user.

NHibernate will manifest this situation as a StaleObjectStateException during the save or commit processes. Your applications should catch that exception and behave accordingly. Usually, it means that you need to show some sort of a message to the user, explaining that the entity was edited by another user, and that the user needs to redo their changes. Occasionally, you need to perform more complex operations, such as offering to merge the information, or allowing the user to decide which version to keep.

Because the first option—displaying a message and having the user redo any changes—is much more common, I’ll show how to implement that with NHibernate, and then discuss briefly how you can implement the other solutions.

One interesting problem that you face right away is that an exception raised from the session means the session is no longer usable. Any concurrency conflict shows up in NHibernate as an exception. The only thing that you may do to a session after it has thrown an exception is to call Dispose on it; any other operation will result in undefined behavior.

I’m going to go back to the edit screen and implement concurrency handling there as an example. I will add a Create Concurrency Conflict button to the edit screen, which will execute the following:

public void OnCreateConcurrencyConflict() {
  using(var session = SessionFactory.OpenSession())
  using(var tx = session.BeginTransaction()) {
    var anotherActionInstance = 
      session.Get<ToDoAction>(Model.Action.Id);
    anotherActionInstance.Title = 
      anotherActionInstance.Title + " -";
    tx.Commit();
  }
MessageBox.Show("Concurrency conflict created");
}

This creates a new session and modifies the title property. This will trigger a concurrency conflict when I try to save the entity in the form, because the session on the form is not aware of those changes. Figure 7 shows how I’m handling that.

I simply wrapped the code that saves to the database in a try catch block and handled the stale state exception by informing the user that I detected a concurrency conflict. I then replace the session.

Figure 7. Handling Concurrency Conflicts

public void OnSave() {
  bool successfulSave;
  try {
    using (var tx = Session.BeginTransaction()) {
      Session.Update(Model.Action);

      tx.Commit();
    }
    successfulSave = true;
  }
  catch (StaleObjectStateException) {
    successfulSave = false;
    MessageBox.Show(
      @"Another user already edited the action before you had a chance to do so. The application will now reload the new data from the database, please retry your changes and save again.");

    ReplaceSessionAfterError();
  }

  EventPublisher.Publish(new ActionUpdated {
    Id = Model.Action.Id
  }, this);

  if (successfulSave)
    View.Close();
}

Notice that I am always calling ActionUpdated, even if I received a concurrency conflict. Here’s why: Even if I got a concurrency conflict, the rest of the application probably doesn’t know about it, and the entity was changed in the database, so I might as well give the rest of the application the chance to show the user the new values as well.

Finally, I only close the form if I’ve been successful in saving to the database. So far, there’s nothing much, but there is the session and entity replacement that I still need to consider (see Figure 8).

Figure 8 Updating Sessions and Entities

protected void ReplaceSessionAfterError() {
  if(session!=null) {
    session.Dispose();
    session = sessionFactory.OpenSession();
    ReplaceEntitiesLoadedByFaultedSession();
  }
  if(statelessSession!=null) {
    statelessSession.Dispose();
    statelessSession = sessionFactory.OpenStatelessSession();
  }
}

protected override void 
  ReplaceEntitiesLoadedByFaultedSession() {
  Initialize(Model.Action.Id);
}

As you can see, I replace the session or the stateless session by disposing them and opening new ones. In the case of a session, I also ask the presenter to replace all the entities that were loaded by the faulted session. NHibernate entities are closely associated to their session, and when the session become unusable, it’s generally best to replace the entities as well. It is not required—the entities aren’t going to suddenly stop working—but things like lazy loading will no longer work. I’d rather pay the cost of replacing the entities than try to figure out if I can or cannot traverse the object graph in certain cases.

The implementation of the entity replacement is done by just calling the Initialize method in this case. This is the same Initialize method that I discussed in the edit form case. This method just gets the entity from the database and sets it into the model property—nothing exciting. In more complex scenarios, it may replace several entity instances that are used in a single form.

For that matter, the same approach holds not only for concurrency conflicts, but for any error that you might get from NHibernate’s sessions. Once you get an error, you must replace the session. And when you replace the session, you probably ought to reload any entities that you loaded using the old session in the new one, just to be on the safe side.

Conflict Management

The last topic that I want to touch upon in this article is the more complex concurrency conflict management techniques. There’s only one option, basically: allow the user to make a decision between the version in the database and the version that the user just modified.

Figure 9 shows the merge screen mockup. As you can see, here you are simply showing the user both options and asking to choose which one they will accept. Any concurrency conflict resolution is somehow based on this idea. You may want to present it in a different way, but that’s how it works, and you can extrapolate from here.

UI for Managing Change Conflicts

Figure 9 UI for Managing Change Conflicts

In the edit screen, change the conflict resolution to this:

catch (StaleObjectStateException) {
  var mergeResult = 
    Presenters.ShowDialog<MergeResult?>(
    "Merge", Model.Action);
  successfulSave = mergeResult != null;

  ReplaceSessionAfterError();
}

I show the merge dialog, and if the user has made a decision about the merge, I decide that it was a successful save (which would close the edit form). Note that I pass the currently edited action to the merge dialog, so it knows the current state of the entity.

The merge dialog presenter is straightforward:

public void Initialize(ToDoAction userVersion) {
  using(var tx = Session.BeginTransaction()) {
    Model = new Model {
      UserVersion = userVersion,
      DatabaseVersion = 
        Session.Get<ToDoAction>(userVersion.Id),
        AllowEditing = new Observable<bool>(false)
    };  

    tx.Commit();
  }
}

On Startup, I get the current version from the database and show both it and the version that the user changed. If the user accepts the database version, I don’t have much to do, so I simply close the form:

public void OnAcceptDatabaseVersion() {
  // nothing to do
  Result = MergeResult.AcceptDatabaseVersion;
  View.Close();
}

If the user wants to force their own version, it’s only slightly more complicated:

public void OnForceUserVersion() {
  using(var tx = Session.BeginTransaction()) {
    //updating the object version to the current one
    Model.UserVersion.Version = 
      Model.DatabaseVersion.Version;
    Session.Merge(Model.UserVersion);
    tx.Commit();
  }
  Result = MergeResult.ForceDatabaseVersion; 
  View.Close();
}

I use NHibernate’s Merge capabilities to take all the persistent values in the user’s version and copy them to the entity instance inside the current session. In effect, it merges the two instances, forcing the user values on top of the database value.

This is actually safe to do even with the other session dead and gone, because the Merge method contract ensures that it doesn’t try to traverse lazy loaded associations.

Note that before I attempt the merge, I set the user’s version property to the database’s version property. This is done because in this case I want to explicitly overwrite that version.

This code doesn’t attempt to handle recursive concurrency conflicts (that is, getting a concurrency conflict as a result of resolving the first one). That’s left as an exercise for you.

Despite the number of challenges outlined in this article, building an NHibernate desktop application isn’t any more difficult than building a NHibernate Web application. And in both scenarios, I believe that using NHibernate will make your life easier, the application more robust and the overall system easier to change and work with.


Oren Eini (who works under the pseudonym Ayende Rahien) is an active member of several open source projects (NHibernate and Castle among them) and is the founder of many others (Rhino Mocks, NHibernate Query Analyzer and Rhino Commons among them). Eini is also responsible for the NHibernate Profiler (nhprof.com), a visual debugger for NHibernate. You can follow Eini’s work at ayende.com/Blog.

Thanks to the following technical experts for reviewing this article: Howard Dierking