What I want from an ORM

Thought I’d blog about some of the things I’d like to see in an ORM in the future, particularly to support DDD cleanly:

  1. No enforced associations – I never want to create an association in the model just to support persistence, regardless of where keys are stored. So if I want to use uni-directional associations then I should be able to do that without having to go for workarounds.
  2. Aggregate locking - Currently, with NHibernate at least, its difficult to lock an entire aggregate. For example NHibernate’s optimistic concurrency approach involves applying a version to rows, however aggregates can span tables so we really want to be able to give each aggregate a shared version (coarse-grained locking approach). See coarse-grained lock pattern.
  3. Validating before saving – I’d like hooks to automatically and cleanly validate an entire aggregate before persistence.
  4. Disabling unit of work – I’d like to be able to disable my unit of work, in many cases when working with DDD the UOW becomes more of a hindrance than anything else. I really want to be 100% sure that the only way to save a Customer is through a CustomerRepository.
  5. Revalidate value objects when reloading – Value objects only validate their data in their constructors, if your ORM does not ensure that a constructor that performs the validation is also used when reloading the object then its possible to end up with an invalid Value object. This is something you definitely want to avoid. Greg Young has raised this issue a few times, including in the NHibernate forum, and made some very good points.
  6. Value objects – Choosing to view something as a value object is a design decision that you make irrespective of the underlying DB design, so whilst the NHibernate component mapping is useful it should be as powerful as the mappings used elsewhere. Unfortunately with NHibernate components don’t support inheritance nicely and if your value object is stored in a separate table things get confusing.

There may be other things I’d want but those are the ones that come to mind.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

2 Responses to What I want from an ORM

  1. Ian Cooper says:

    HI Colin,

    Thought I would comment at your new home.

    I agree with a lot of what you are saying (feeling your pain on 5 and 6)

    I’m not sure that I agree with 4. My understanding of a repository is that it has collection semantics i.e. appears like an in-memory collection would.

    With an in-memory collection I may add or remove items, but I don’t ever update them. With an in-memory collection I don’t have to re-add, just because I add a child to the parent that is already stored in the list.

    Turning off unit-of-work would seem to me to break the collection semantics approach of a repository, because you now have to perform update operations. That means that the knowledge that I am using some sort of external persistent store bleeds into my domain model. I don’t really want that. I like what unit of work gives me in this regard, a lack of difference between in-memory and persistent storage.

    I recently changed our repository base class to have an op named Add instead of Save because folks here got confused as to when they had to tell the ORM about their changes. If you use Add and Remove instead of Save and Delete its is a lot more obvious when you should use them.

  2. Colin Jack says:

    Hi Ian,

    Good comment/point and you could be right about 4, I know it’s questionable and if we had 3 then it wouldn’t be an issue.

    However if we don’t have 3 then I like the idea of switching off the UOW because otherwise I’m relying on convention to ensure that people validate aggregates before persistence or have to do some incredibly nasty workarounds to make that automatic (such as exceptions from interceptors or whatever).

    On the aggregate validation angle, whilst I like the idea of having a repository behave like an in-memory collection doing so does make the aggregate invariants rule hard to apply:

    “When a change to any object within the aggregate boundary is committed, all invariants of the whole aggregate must be specified”

    If we follow this rule but also allow clients to update the aggregate piecemeal, rather than following Greg Young’s always valid approach, then committing does become an event that we are interested in. Unfortunately if the UOW takes care of it all for us and doesn’t give us a nice way to hook in then we’re left, primarily, with conventions.

    I also find that the UOW is not a feature I find massively useful when working with DDD since I know which aggregates are being affected in a particular request. I thus don’t see losing it as being a big deal.

    So yeah I agree with you in general and maybe I shouldn’t have added 4 :)

    Oh and Add/Remove, yeah I like that approach but these days most people seem to use freely available repository interfaces that tend to have Save/Update.



Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>