I am developing a large software project using DDD (Domain-Driven Design). I have an entity that acts as an aggregate root, let's call it Root
. This entity refers to a collection of child entities of the type Child
.
Because the use of this Child
entity is an implementation detail that does not matter to clients of my Root
entity, those children are solely managed by the Root
entity, meaning the creation of new children and the removal of existing children all takes place in according methods of the Root
entity. Pseudocode could look the following
class Root
{
private Collection<Child> children;
public void addChild(ChildParameters params)
{
this.children.append(new Child(params));
}
public void removeChildByCriteria(Criteria removalCriteria)
{
Child foundChild = this.children.findByCriteria(removalCriteria);
if (foundChild) {
this.children.remove(foundChild);
}
}
}
I think this is a very clean approach if you only look at the object model. However, this has to be persisted somewhere, so a Repository
takes care of storing a Root
entity and its children in a database.
I am struggling now with finding the right place for the logic to remove a persisted child from the repository (and therefore the database). Is it ok to let the implementation of the repository find orphaned children and remove them automatically? Or is the deletion of orphaned children domain logic that should be explicitly coded inside the root entity by passing a repository to the removeChildByCriteria
method like
// ...
public void removeChildByCriteria(Criteria removalCriteria, ChildRepositoryInterface childRepository)
{
Child foundChild = this.children.findByCriteria(removalCriteria);
if (foundChild) {
this.children.remove(foundChild);
childRepository.remove(foundChild);
}
}
// ...
Or is it all wrong to place the logic to manage the hierarchy inside the root entity and instead a domain service or domain events and according listeners should be used?