Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD find out ID of child element after saving with Hibernate

public class AggregateRoot {
     private Integer id;

     private Set<Child> children;
}

public class Child {
     private Integer id;
     private String name;
}

Imagine that you need to save Child and to send his ID to the some external system. In DDD you will save child with code similar to this:

AggregateRoot aggregateRoot = aggregateRootRepository.getById(id);
Child child = new Child();
child.setName("Sun");
aggregateRoot.addChild(child);
aggregateRootRepository.save(aggregateRoot);
externalService.postSavedChildId(child.getId());

Of course child.getId() will return null because it is not in persistence context. Any idea how this case should be handled in DDD?

like image 272
mommcilo Avatar asked Jan 15 '16 15:01

mommcilo


2 Answers

There are two problems in your case, which I will address separately:

  • How should we hand out IDs of non-aggregate-root entities?
  • How do we obtain an ID of an entity before saving, when using DB-generated IDs?

References to Non-Aggregate-Root Entities

DDD suggests that aggregate roots carry global IDs, while "inner" entity IDs have only local significance. So you should not expose the inner ID alone, as it will not uniquely address the entity.

  1. Split the two entities and make the inner entity an aggregate of itself. Now it has global identity and becomes addressable from the outside world.
  2. If (1) does not make sense in your domain, expose a combined ID to the external system. You must be able to separate the combined ID into the aggregate root ID and the (local) inner entity ID.

DB-Generated IDs

Using DB-generated IDs does not fit well with DDD for the reasons you experienced. The best approach is usually to use generated random IDs. This answer has more information about the topic.

Side Note

From reading your question, I get the impression that you take a rather DB-centric approach (using DB-generated IDs is one indication of that). When using DDD, try to focus on the domain model first and build the DB infrastructure around it.

like image 87
theDmi Avatar answered Oct 01 '22 14:10

theDmi


Imagine that you need to save Child and to send his ID to the some external system

You cannot do it. Entities within an aggregate have local identities, which means it is impossible to access these entities from the outside the aggregate. The only entity accessible from the outside of an aggregate, meaning having a global identity, is the aggregate root.

So it seems the entity, whose ids you want to provide to an external system, is actually an aggregate root.

Another question is, why do you expose the database ids of entities of one system to another system? Systems should not depend on the database ids of other systems. They should use business ids instead.

like image 32
Adam Siemion Avatar answered Oct 01 '22 12:10

Adam Siemion