Simple NHibernate Example, Part 5: Repository Testing

Bill McCafferty has released his updates to his NHibernate Best Practices article. The article is fantastic. It is listed as an advanced topic, but if you follow every link and study the topics in his article, the article makes for as great a comprehensive introduction as any… Go read it now.

In the last few posts, we explored very simple concepts from the point of view of DDD and BDD/TDD. In this post, I will put together a very simple testing harness to show how to roll together these concepts in the context of NHibernate.

Begin by reviewing the interface created in Part 3. In that example, the Repository interface is placed at the domain level (Foo.Domain.Repositories.DealerRepository – and no, I don’t use the I in my interfaces). Again, the idea is that a Repository is a domain level concept for managing the lifecycle of Entities. However, the implementation of the persistence mechanism is abstracted from the domain’s point of view.

We will create an implementation of the repository interface for NHibernate. I know there are many ways to implement repositories, but I’m keeping it easy for this example.

One other side note – this example is copying over the same specs/tests from Part 3 for my NHibernate tests, but you could imagine reusing them somehow by injecting in mock or NHibernate implementations of the interface. I really haven’t explored an idea like this, but if somebody has, let me know.

Everything needed for this repository example is in the sample zip file. Go download the zip file now. You will want to focus on the Foo.Data.NHibernate and Tests.Foo.Data.NHibernate projects to see how it all works. Post your questions here.

 

Supporting Items

The database schema is included in the solution if you would like to run that to build the FooDomain database and Dealer table.

This Dealer domain object to table mapping file is located in the Foo.Data.NHibernate project under the DomainMappings folder. The file also contains a component mapping for a phone number Value object (the fax number and contact phone number). Let’s just say that it is important for us to store the phone number broken down into its constituent parts (area code, exchange and SLID) for this example.

In the mapping file, I use of the access=nosetter.camelcase access attribute. This tells NHibernate to set the field values directly rather than through the properties (since no setter is available, as we would like to keep IDs and value object references immutable, as you will see in a moment).

I use a customized version of nDbUnit to allow for rollbacks of transactions rather than explicit delete. My customized version is included in the project file (which is what makes the zip file pretty big) and could use some cleanup if you want to take that on. :) The project, Tests.Foo.Data.NHibernate contains the xsd used by nDbUnit and you can review the tests to see how it is read into.

My customizations also reset the identity value on the Dealer table
after a DeleteAll is called.

I did not explicitly call flush after the NHibernate save() calls, which
would immediately write the data to the database. The flush is done automatically since
NHibernate has to go to the database to pull the identity value and set
it on the domain object. This is an important point since NDbUnit needs
to have some data to read from the database. :)

Finally, the tests show how to extract the
NHibernate transaction and pass it to NDbUnit in the GetTransaction()
method.
 

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Nelson Montalvo

I’m a software developer who loves .NET, Agile methodologies, Test Driven Design, Domain Driven techniques, and open source tools. Don’t get me wrong, I also like to use a thing or two that Microsoft creates besides .NET itself. :) In my “spare time” (when is that, anyways?) I like riding my motorcycle (http://sportbike.nmonta.com), reading, watching movies (lots of movies), working out, and hanging out (good conversation, good beer, good times). Look me up in Facebook, Linked In or Plaxo. My personal code blog is http://codemonkey.nmonta.com.
This entry was posted in NHibernate. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

6 Responses to Simple NHibernate Example, Part 5: Repository Testing

  1. jlockwood says:

    ((IDo)this).lol

  2. jack says:

    HI Nelson,

    I have been scrawling the web looking for information to help me implement a repository pattern for my custome layered architecture .

    i have read the repository pattern section of DDD, but what I have been seen arround on the web as implementation is no big difference from a wrapper of all DAOs into one class which is called “repository”.  

    So what are the key differences between your Repository pattern implementation and simple DAO pattern implementation.

    I gues repository and DAO have two different strategy for getting objects out of the database.  

    With the repository pattern, the root object ( aggregate root) is obtained first, and other associated object are loaded lazily as required by navigation down the association.

    For example to abtain a lineItem belonging to an order we do order.items.getItemByID(paramID);

    where order is a root aggregate.

    However, using DAO  we simple do itemDAO.getItemsByID(paramID); where itemDAO may come from a factory.

    I do not see code or tutorials showing how to navigate down the root aggregate associations. Any suggestions ?

  3. I suppose that this one’s up in the air in terms of differing opinions, so I’ll caveat with IMO… lol.

    Pretty much, a Repository (per Evan’s DDD book) acts as the “starting point for the traversal to an ENTITY or VALUE in the middle of its life cycle.” Strictly speaking, it’s a DOMAIN level concept abstracting out the work needed to acquire that aggregate root. Note that I have not talked anything about databases, DAOs, and whatnot. I think that it’s easy to go to that level, but remember that the repository could be talking to an in-memory DB, a web service, and whatever else. The key elements to me, with the implementation of a repository, tend to be session/transaction management and “lazy” traversals.

    All that being said, I mostly make interfaces out of the repositories in my domain. From here, I can implement the repository however I want, injecting the implementation as needed. A simple example utilizing NHibernate is here: http://codemonkey.nmonta.com/2008/04/02/simple-nhibernate-query-using-createcriteria/ and more information on implementing repositories are here: http://martinfowler.com/eaaCatalog/repository.html.

    But getting back to your original points:

    - I do not believe a repository HAS TO BE a wrapper or generic crud operator around “all DAOs.” If the point of the repository is to provide the domain with some sense of how to get the aggregate root, why can’t the methods be business specific as opposed to generic? GetMyBadAssVehicle(string nameOfDriver) vs GetItem(CriteriaObj criteria) where criteria might contain BadAss = true and the name of the driver. As your domain requirements change, so might your repository requirements, to the point where it makes more sense to have a generic repository.

    - You do not ALWAYS have to traverse an aggregate root to reah another object. There are of course different ways to implement this, but based on your example, does the item have enough significance to be its own aggregate? If so, then it might be easier to build a repository querying that. If not, would you inject your repository/DAO implementation into the aggregate itself, so that lazy loading can occur? Or better yet, why not use NHibernate or other ORM and just save yourself all that trouble? :)

    I’ll see if I can put together a quick NHibernate example of lazy root traversals, so you can see it in all its glory. :)

  4. jack says:

    Hi, thanks for you quick reply.
    You have put more light on the issue. Good work!!
    I am eagerly waiting for your NHibernateRepository example with lazy root traversal. A simple example, just illustrating the methodology will be ok. You did not need to provide full working codes.

    The first link you provided me did not work. But I successfully make a trip to Fowlers website to see his own version of a repository.

    Here are some few more questions
    “The key elements to me, with the implementation of a repository, tend to be session/transaction management and “lazy” traversals.”
    1)It is logical true that the first time setup of the session is expensive. some people have suggest to store it in the httpcontext variable. Which means use one session per context. (a) When is it right to use one session per context ? and (b) when it is right to use one session per “unit of work” ?
    2) Evans of DDD, suggest that transaction management should be kept out of the repository and managed by the consumer of the repository since the consumer of the repository has a better knowledge of its “unit of work ” boundaries. (a) what is your suggestion on this point?
    (b) let assume that our repository is a public tap in a restaurant ( it provide us with water on demand). In the past when you want to wash you hands, you will move to the tap (new datacontext), open the tap (begintransaction), water flows out, you wash you hands, you close the tap (endtransaction) , and move away (dispose datacontext).
    Experience shows that obviously the user don’t care about the opening and closing of the tap. all the user wants is water to wash their hands. Today there are some intelligent taps with infra ray that will automatically open when you move infront of them and automatically close when you move away. So how can we implement an intelligent repository that will internally handle sessions and transactions issuis which are obvious not the job of our business domain but that of the Data Access Layer.?

    Thanks for your work so far.

  5. Josh Schwartzberg says:

    Hmm, the download link for this article doesn’t work anymore. Any chance you could fix that?

  6. @jack

    Sorry, haven’t had much time and still don’t, so here goes:

    1. I believe that a) it’s more appropriate to use it when your unit of work is, for example, at the request level in a web application. I think this is referred to as the session per request. When a request comes in to an asp.net application, it normally last only a few seconds, so opening a session at the beginning of the request is ok. Honestly, I haven’t thought through a lot of scenarios like this so, but for both a) and b) I would say that you are putting the session into context and just reaching into context whenever you need session. The difference is whether you are reaching into httpcontext on a web application or call context for pretty much all other types of apps. Please search for the difference between the two, it’s important. Also, NHibernate 2.0 nicely handles the difference between the two with a session context manager (I’m not sure if it was available in earlier versions).

    Finally, note that you can have more than one session open per context. the other sessions might point to other databases, for example. Your repository would have to konw how to ask for the correct one. Perhaps injecting the repository with some way to do that would facilitate this.

    2a) I fully agree. Transaction management doesn’t necessarily have to be explicit at the app/domain level. It can be hidden through a facade: (UnitOfWork.InitWork) opens a new transaction under the covers, for example. For the most part, allow the transaction management to occur outside the repositories.

    2b) I like the analogy.However, I don’t know if the repositories should be handling session/trnsaction issues. I suppose there are cases where you might want to. I keep that at the app level. So I suppose some of your internals can be exposed at the app level (via exceptions), but this is usually not a big deal if you allow your facade to handle the issues by delegating (UnitOfWork.RecoveFrom(blah) or whatever).