How can I cascade changes from one aggregate root to another?

I’m having trouble modelling a relationship in DDD. I have four entities:

  • Claim – defines access to a Service.
  • Service – a web service. A Service has many Claims and can belong to any number of Teams.
  • Role – contains a collection of Claims from any number of Services. Roles always belong to a Team.
  • Team – contains a collection of Roles, and Services.

When I remove a Claim from a Service, it should also be removed from all Roles that have that Claim assigned to them. Equally, when I change the name of a Service, that name should be reflected in all the Teams.

I currently have a Service aggregate root (to allow Services to be added and altered independently of any one Team), and a Team aggregate root (to allow management of Team-specific Roles). This creates two problems:

  • Changes in the Service aggregate are not reflected in the Team aggregate
  • When a Claim is removed from a Service, there is no way to cascade this into the Team’s roles.

There’s something clearly horribly wrong with my model, and was wondering if anyone can illuminate where I’ve gone awry.


Why does a Role have a direct relation to Service, when the relation obviously requires a Claim to exist? Just forget about that one.

Respectively where is there a relation between Service and Team? Add an indirection via an Ownership entity to model that.

Choosing Team and Service as the only root aggregates is correct.

Team    1 <-> * Role
Role    1 <-> * Claim

Service 1 <-> * Claim

Team    1 <-> * Ownership
Service 1 <-> * Ownership

By making the relations traversable in both directions, you can already reach each entity required to access all related information required.

There is no actual need to ever store Service names in a Team, that information can be aggregated by navigating both along the Claim and the Ownership relations.

As a Claim holds both a reference on a Role and on a Service, you must traverse both parents when deleting a Claim. The same goes for Ownership. It doesn’t matter which parent owns the child and which just holds a reference, that’s just an implementation detail.


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *