Querying is a business concern

time to read 3 min | 412 words

A lot of people moving from hand-built / code-gened DAL to NHibernate seem to encounter the issue of anemic data layer. NHibernate subsume all the responsabilities, leaving the developer with just managing the session and maybe adding a couple of Get/Save methods. It tends to bother some people, who are used to data layers that does quite a bit more.

A more important concern is that you end up putting query logic inside your business objects, and that breaks the way things should happen according to the Ancient Wisdom. As far as I can see it, NHibernate is dealing with the mechanics of querying the database, leaving you to work with the model. When I put it this way, does it make more sense?

You are telling NHibernate, in the terms of the model, what you want to get back, and it does it.

If I want to display to the user its next actions, I need to ask: "give me all the users's actions whose state is not completed, ordered by date and then importance". This is a business decision, in my book, and expressed in code, it would turned out like this:

ICollection<Action> actions = Repository<Action>(
  Where.Action.User == CurrentUser &&
  Where.Action.Status != ActionStatus.Complete,
  OrderBy.Action.Date, OrderBy.Action.Importance
);

You could put this in a method called DataLayer.GetUserNextActions(User user), but I think that when you get to this point, it is getting to be pointless.

There are two cases that I would like to point out as exceptions:

  • Very complex queries should be put in a seperate class, I like to use [Entity][Scenario]Finder for those classes, but I don't really think about those as data layer classes.
  • I prefer to use named queries over inline HQL. It is mostly left over from the "Don't Put SQL In Your Code", I admit, but I still prefer this.