DDD – How to Add New Child Entity to a Repository

domain-driven-design

I'm new to Domain-Driven Design and I'm using it in an application I am developing. I'm getting stuck on how to put new entities into a repository. My repository is just a big collection of entities that I can query.

One of my entities can have child entities, so I gave it an AddChild() method. It uses a factory to instantiate the child and adds the child to a child collection.

How should I add this new child entity to my repository?

I don't want the caller of AddChild() to add it, and I have read that entities themselves should not access repositories.

Best Answer

I have a similar situation, in that my domain model consists of a web of linked entities. I have solved it in this way:

For each Entity type, I have a corresponding EntityRepository. The Entities are completely unaware of the existence of the repositories.

Each EntityRepository type maintains a cache of the Entity instances that it knows about (those that were retrieved from that repository), and it has references to the repositories of linked entities.
When saving an Entity in its repository, the repository checks if it knows about the entity and either inserts it in the database (and its cache), or it updates the database. For linked entities, the repository requests the repository of the linked item to save that item and then it updates the database links between the entities.
Entities that are disassociated from each other are detected automatically in a similar way in the repositories.

To give an example in pseudocode:

// Entities
class Child { }

class Parent
{
    addChild(Child);
    Child[] getChildren();
}


// Repositories
class ChildRepository
{
    save(Child entity)
    {
        if (cache.contains(entity))
            updateDatabase(entity);
        else
            AddToDatabase(entity);
    }
    Child[] cache
}

class ParentRepository
{
    save(Parent entity)
    {
        if (cache.contains(entity))
            updateDatabase(entity);
        else
            AddToDatabase(entity);
        childRepo.save(entity.children());
        updateParentChildLinkTable();
    }
    Parent[] cache
    ChildRepository childRepo
}