Thursday, August 23, 2007

NHibernate Gotchas - Living With Legacy Databases

As we've used NHibernate more and more we've begun to hit against issues, particularly when working against a "legacy" database. So if you are working against a green fields database then your probably fine, you can design from the domain down but if you're not then I think two issues in particular are worth bearing in mind:

  1. Inability to map inheritance at the component level.
  2. Inability to map unidirectional many-one in a satisfactory way in some cases.

Before I continue I should say two things. The first is that the class names are unimportant, I made them up as I don't want to use real class names or examples from our project. Secondly I am not going to provide solutions, I don't know if it’s even possible for an ORM solution to handle these issues better than NHibernate does but you should still know about them.

Components And Inheritance

NHibernate component mappings are great and can improve your domain model but there are limits.

Take the example of an Customer table that has 50+ columns, don't ask me why but it does. You want to redesign the table but thats something to be planned and executed carefully, DB refactoring is painful especially when you have multiple legacy systems and reports/DTS's working against the database.

So for now you want to design your domain model to have a core Customer class and then lots of little inheritance hierarchies off it. For example if the Customer came directly from your Web site then maybe 5 fields in the database are used and if they came indirectly its a different 10.

In each of the two cases you have different behavior and certainly different validation requirements so you decide to have an ICustomerSource interface (making this up as I go) with two subclasses called DirectCustomerSource and ExternalCustomerSource. The Customer will then have a reference to an ICustomerSource which it will be passed in it constructor.

The problem is you cannot do this because your mapping would have each subclass of ICustomerSource mapped as a component, meaning that when the Customer is saved so should the ICustomerSource. The problem is that the component mapping does not support mapping inheritance so, as far as I know, you are slightly stuffed.

You could certainly subclass Customer and get around it that way but that doesn't always work and certainly wouldn't work for us because we actually want to have multiple little class hierarchies hanging off Customer.

I've logged this "issue" in the NHibernate JIRA.

Unidirectional Many-One Associations

Let’s say we have Order and OrderItems. The Order is the root of an aggregate containing OrderItems. In this case we might actually want to do this in the domain by having the Order have a collection of OrderItems. Maybe not for this situation but we often do.In the domain we want to make the association unidirectional though, we can go from a Order to an OrderItem but we don't want to do the reverse association.

Our database design has the ID of the Order as a foreign key in the OrderItem table. Many people see this as a valid database design and so it’s quite possible this is the way you have it done.

The problem is this isn't going to work unless we do one of two things:

  1. Make the foreign key in the OrderItem table nullable.
  2. Add the association from OrderItem to Order.

This topic is discussed in depth in the forums:

  1. Describes why Hibernate works that way.
  2. Another post with more context.
  3. Yet another post on it.

Of course you can just use one of the work arounds but its worth knowing that this issue exists as it can catch you out. I've logged an issue in the NHibernate Jira about it.

Summary
Neither issue should convince you that NHibernate is a dead loss, it is still magic but it does have limits and you need to be aware of them.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

TypeMock v IoC (Round 1)

Lots of discussion has kicked off about TypeMock v IoC:

  1. Pro TypeMock - I don't agree with some of this, though I can see the authors point. For me the arguments for depdendency inversion are all in Robert Martins excellent book.
  2. Good Summary - Agreeing with both camps seems sensible :)
  3. Pro DI - Good summary of where DI is useful.
  4. Pro DI 2 - Another discussion on where DI can help.
  5. DI In Context - Really good post with the start of a (hopefully) long and important discussion of how DI relates to different layers.
  6. DI and other patterns - Interface programming, SRP and the rest.
  7. More Pro DI - Another good article on it.
Ultimately I think both have their place and some of the comments are also insightful, in particular I liked Mats Helanders comments to Ayendes post:

When writing an application, you may well be able to analyze in advance to see where you need pluggability points and provide interfaces there. Adding interfaces where you don't anticipate any use for them would of course be a violation of YAGNI.

I really like interface based programming and buy into it. In particular Robert Martins book (one of my favorite programming books) really goes into depth about how to decouple systems. However there is a cost and if you apply the principles too widely I think you get a mess, in particular when you are talking about your core domain/business classes.

I also don't fully agree with the vociferous arguments against TypeMock, I think it can be quite useful where you've looked at your design and decided your happy with it but you also want to do a bit of mocking.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Testing the Domain

We've been having a lot of discussion in our company about how to test the domain and we've learned a lot from the discussion that I thought was worth sharing.

State Testing
My general view is that testing your domain classes against their public interfaces using state testing is a valid choice. The way we have chosen do this is:

  1. Only use real domain objects in the tests, no mocking.
  2. In general test against the public interfaces of public domain classes.
Eric Evans contributed to a DDD forum thread about this topic and I have to say I agree completely.

Where it does get interesting is where we are using state (as in state pattern) based validation in our domain objects. Nilsson summarizes the problem:

"In reality, adding rules also creates problems with testing. You nee to setup instances to correct states. You can write test helpers (such as private methods) for dealing with that, but it's still a hindrance."

The solution we've gone for up till now is an ObjectMother based approach, so for instance we have a CustomerObjectMother than can produce Customers in all sorts of different states. So if you are testing an Order and you need a Customer in the Active state then you can call into the CustomerObjectMother to get it. The object mother classes have all sorts of different creation/attachment methods.

This approach is definitely not without its flaws, including:
  1. The domain should be enforcing/encapsulating quite a lot so testing it can be more complex than testing the individual (encapsulated) classes within the domain.
  2. If we modify the Customer code and break it then its possible lots tests will break because they use the Customer class in the SUT setup phase (e.g we need a Customer even though we're testing the Order).

The main advantages of the approach are:

  1. Tests at the public interface level mean that we can refactor within the domain safely because they act as a good safety net.
  2. They point out places where the design is a bit overly complex (e.g. if we have lots of Customer states then the ObjectMother has to handle them all).

Decision Time

We've decided to have two levels of tests within the domain, we haven't got good names but essentially they will be:

  1. Domain Tests - Testing at the public interface with real objects, mainly state testing.
  2. Interation Tests - Detailed white box tests going right into the internal classes within the domain, mocking and doing interaction testing as appropriate.

This seems a good compromise, you are testing the public interface so all us TDDers can refactor happily below the public interface level but we've got detailed tests for the smaller classes.

The next question is how many of each test to have, hopefully good coverage by both and a lot of reuse but we'll have to see how that goes. Good.

Interaction Tests

However we have to decide how to mock the domain classes. I'm not at all in favor of covering my domain classes in interfaces, some people do it but there are valid reasons not to not least that the interfaces we put in for mocking hide the real meaningful abstractions within the domain.

Plus in this case we'll often be mocking classes internal to the domain (as in accessibility of internal in .NET). We can do this because we use InternalsVisibleToAttribute to give our unit tests access to the internals of the domain but do we really want to design our internal classes so that they are more easily mockable, then use depdency injection.

An example might help here, lets say our Customer class uses a custom collection called CustomerAddressCollection. This collection has complex logic to track the temporal nature of addresses and the fact that addresses have different purposes (home/work). Users of the Customer don't even know about this custom collection though as we've encapsulated its very existence.

We've tested CustomerAddressCollection but we want to test that Customer works correctly with it, and in this case we want to write an interaction/mocking test. It seems to me we have two choices:

  1. Give CustomerAddressCollection an interface then allow it to be injected into Customer and use Rhino Mocks for the mocking.
  2. Use TypeMock to mock CustomerAddressCollection, mock the methods that we expect Customer to access and then check Customer accesses it correctly.

For now I'm thinking the second option is better.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, August 21, 2007

The Domain And Testing Dependent Layers

I've blogged seperately about the arguments for mocking domain classes when testing the domain itself.

However we also need to consider how to deal with situations where we want to be able to mock out the domain when testing another layer, in particular we need to consider it because Ayende has just posted a good blog article that relates to the topic.

I'll take the example that I put in Ayende's blog. Lets say I have an application layer service that calls to a repository, then to an infrastructure service, then into a domain service/entity and then returns. I want to test the application layer service. In that case I can inject in the repository and infrastructure service to do interaction testing, but would you also inject the domain service/entity.

I think there are a couple of options:

  1. Interfaces - On any domain objects we need to mock.
  2. Virtual members - Any member we need to mock would be virtual.
  3. No Domain Mocking - Don't mock domain classes when testing other layers.
  4. TypeMock - Oh dear, into the lions den....

Interfaces

An interface on every domain object that we need to mock, sure its an option that some people go for but I'm with the group that argues you should only use interfaces in your domain if they are useful. I've blogged about this before but do I really want to be able to replace one Customer with another, probably not so its not a useful extension point to introduce and it ends up introducing complexity I don't need.

We've also gone for a pure (or as pure as we can get) persistence ignorant approach, so I don't want to then have to mess with my domain to get it to fit in with IoC and mocking frameworks.

Virtual Members

Interfaces are not the only way to mock domain objects, Rhino Mocks can mock virtual members too and since most of our aggregate roots are lazy loadable their members are virtual (NHibernate requires this).

This would seem to me to be a half baked solution, if we're going to mock why not use TypeMock.

TypeMock

It is a hugely powerful tool and you can misuse it. However in this case we'd have chosen to use it in a way that lets us maintain the design we want, which to me is an acceptable useage.

No Domain Mocking

Should be an option, why not let the Application layer service call into the domain service/entity.

Our domain is POCO and in fact very rarely calls out to the repositories directly. This isn't the way everyone goes as can be seen here and here.

We can get away with this thanks to NHibernate, in fact the only time our domain classes go to repositories to get reference data and when we go with that approach we hide it behind a Registry/Service Locator. By and large this works fine, where it doesn't we use a special coordination layer, part of the domain but with different responsibilities.

So using the domain should be simple.

Summary

So far we haven't needed to mock the domain classes when testing at a higher level, if we do I'm thinking that using TypeMock is a good option.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Friday, August 10, 2007

NHibernate Gotchas

Although I love NHibernate we do seem to be hitting up against some of its problems these days, I've discussed some of them here but I wanted to document a few more.

Reference Data

You cannot easily map lists of essentially static data.

Dictionaries/Collections Containing Other Collections

We are currently restructuring our domain model massively, one of the main reasons is so that we can exploit the Party archetype pattern. We were able to redesign the DB at the same time as the domain so we didn't hit up against the normal set of issues that stop us redesigning our domain without changing the DB. However we did meet other issues.


For example in the party pattern a particular role (Customer) could be involved in multiple relationships. We need to have a relationship between the role and the relationship and it would seem sensible to have a dictionary keyed by PartyRelationshipKind (enum) where the value was an IList of PartyRoles.

The performance would be good, it'd be clean domain wise and we'd all be winners. Only slight problem is that it isn't supported, as is discussed in the forum entry. We ended up basically mapping the relationships into one big IList and then iterating through it when we wanted to get those that related to a particular PartyRelationshipKind.

Generics
Although NHibernate supports generics the support is limited, in particular you may come upon the following issues:

  1. Mapping a generic class - Currently not supported. You can work around this by mapping a concrete class that inherits from the generic base class.
  2. Mapping classes inheriting from a generic baseclass - A JIRA article can be found here, the solution is to map each of the subclasses seperately.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, August 07, 2007

Linq And Specifications

We've been puzzling about how to improve our use of the specification pattern.

In particular currently if we have a specification CustomerNameSpecification that acts over objects in memory then we want it to be joined up to the assoicated GetCustomersWithName method on the CustomerRepository.

Up till now this has been difficult, we don't want NHibernate to leak into the domain and so we've just kept the specifications as operating over in-memory objects and the associated queries on the repositories use ICriteria/HQL.

Then Linq came along. Now I'm no expert on it, tried it out an age ago and since I've only been reading about it but it does look interesting and there have been a few interesting articles about it, both from a single blog:

  1. Persistence Ignorance And Linq - Good introduction to how Linq can support DDD in .NET.
  2. Linq and Specifications - The section "Specifications and Repositories" is interesting. There is obviously a tradeoff as the specification gets more complex/abstract but the advantages could make it worthile.

Anyway its interesting stuff.

The specification approach is great and the idea of having in-memory repositories using Linq is detailed too. Neither are new ideas but both could be very important in the future and solve problems and its good to have articles on them. Also with Linq coming to NHibernate it'll be interesting to see what is possible.

Part way down one of the articles is a link to an example app, will have to look at it at some stage.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone