9

On page 382 of this book there is a passage talking about using value objects in aggregates, under the (entity) root. There is an example of Product that, besides other values, contains a Set<ProductBacklogItem> - collection of entities.

Now, Vernon tries to explain why ProductBacklogItem is an entity and not a value object:

There are good reasons why ProductBacklogItem is modeled as an Entity rather than a Value. As discussed in Value Objects (6), since the backing database is used via Hibernate, it must model collections of Values as database entities. Reordering any one of the elements could cause a significant number, even all, of the ProductBacklogItem instances to be deleted and replaced. That would tend to cause significant overhead in the infrastructure. As an Entity, it allows the ordering attribute to be changed across any and all collection elements as often as a product owner requires. However, if we were to switch from using Hibernate with MySQL to a key-value store, we could easily change ProductBacklogItem to be a Value type instead. When using a key- value or document store, Aggregate instances are typically serialized as one value representation for storage.

I don't understand why the Repository implementation determines if some model is going to be an Entity or Value Object? If we go to the key-value store, we still may have ordering he is talking about.

Do you think this make sense?

2 Answers 2

2

I know this question is from some years ago, but I've been dealing with a similar modelling problem at the moment, and perhaps it will be useful to someone else to see what alternative opinions are out there.

You're right, this section is a bit misleading and contradictory, as so much time is spent in DDD indicating that the domain design shouldn't be driven by persistence concerns.

If I'm taking a guess, what is actually being referred to is the immutable nature of Value Objects. In this example he talks specifically about the ordering of the Backlog Items. Value Objects are immutable, so changing the order of 1 Backlog Item could result in "significant number, even all, of the ProductBacklogItem instances to be deleted and replaced".

So although technically still driven by the infrastructure, ultimately to retain order in a SQL solution, the Value Object must be mutable, and therefore not a Value Object. This problem doesn't exist in an NoSQL solution where "Aggregate instances are typically serialized as one value representation for storage." So you shouldn't let persistence drive your design, but to allow re-ordering there is no way around not having the object be an Entity

This is where my own modelling problem came into the picture. If the order of the items is important, then I've been wrestling with the idea that those objects must be Entities... because if order is important, then identity must be important as well. ie. How do you re-order items if each one doesn't have a specific identity? If order isn't important, then it's now just a collection/bag of values, and so now they are likely Value Objects.

The approach I've been considering is that the order should be maintained by an Entity, in this instance OrderedBackLogItem. But this entity contains a ProductBacklogItem Value Object and an ordering attribute.

Other alternatives are the the approach Vernon has taken (one Entity), or the collection itself is a Value Object, and so the entire ordered list is destroyed and re-created each time.

I'm still in two minds as to whether each item in a list must be an Entity if re-ordering is important.

1

The reason is that SQL databases store the objects in a relational way - items are stored in different table than aggregate root and they reference back to aggregate root by IDs. So using of MySQL requires to model items as entities that are persisted in separate table where they obtain primary id (with auto increment).

In key-value stores eg. MongoDB one can store the whole collection of items as part of the aggregate root. The items would not become separate entities (in its on table) and thus can be modelled as value objects.

Eg. Blog has Comments stored as collection within:

{
  _id: 1,
  title: 'Some title',
  body: 'Blog body',
  comments: [{
     person: 'John Smith',
     comment: 'First comment of the blog',
     created_at: new Date()
  },
  {
     person: 'Peter Jackson',
     comment: 'Second comment of the blog',
     created_at: new Date()
  }],
}
1
  • 1
    This is not entirely true. "So using of MySQL requires to model items as entities that are persisted in separate table where they obtain primary id (with auto increment)." In DDD it is allowed that value object have primary key, but it is not part of model interface (i.e. it is stored in private fields). And Vernon itself says this and uses this in examples. Therefore my confusion.
    – lawpert
    Commented Nov 7, 2014 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.