DDD 在使用 Hibernate 保存后找出子元素的 ID
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;
}
假设您需要保存 Child
并将他的 ID 发送到某个外部系统。在 DDD 中,您将使用类似于以下的代码保存子项:
AggregateRoot aggregateRoot = aggregateRootRepository.getById(id);
Child child = new Child();
child.setName("Sun");
aggregateRoot.addChild(child);
aggregateRootRepository.save(aggregateRoot);
externalService.postSavedChildId(child.getId());
当然 child.getId()
将 return 为空,因为它不在持久性上下文中。知道应该如何在 DDD 中处理这种情况吗?
Imagine that you need to save Child and to send his ID to the some external system
你做不到。聚合内的实体具有本地身份,这意味着不可能从聚合外部访问这些实体。唯一可从聚合外部访问的实体,即具有全局身份的实体,是聚合根。
因此,您要向外部系统提供其 ID 的实体似乎实际上是聚合根。
还有一个问题,为什么要把一个系统实体的数据库id暴露给另一个系统?系统不应依赖于其他系统的数据库 ID。他们应该改用商家 ID。
你的情况有两个问题,我将分别解决:
- 我们应该如何分发 non-aggregate-root 个实体的 ID?
- 当使用 DB-generated 个 ID 时,我们如何在保存之前获取实体的 ID?
对Non-Aggregate-Root实体的引用
DDD 建议聚合根携带全局 ID,而 "inner" 实体 ID 仅具有局部意义。所以你不应该单独公开内部 ID,因为它不会唯一地寻址实体。
- 拆分两个实体并使内部实体成为其自身的集合。现在它具有全球身份并且可以从外部世界寻址。
- 如果 (1) 在您的域中没有意义,请向外部系统公开组合 ID。您必须能够将组合 ID 分成聚合根 ID 和(本地)内部实体 ID。
DB-Generated ID
由于您遇到的原因,使用 DB-generated ID 不适合 DDD。最好的方法通常是使用生成的随机 ID。 有关于该主题的更多信息。
旁注
通过阅读你的问题,我得到的印象是你采取了相当 DB-centric 的方法(使用 DB-generated ID 就是一个迹象)。 使用 DDD 时,首先尝试关注域模型并围绕它构建数据库基础结构。
public class AggregateRoot {
private Integer id;
private Set<Child> children;
}
public class Child {
private Integer id;
private String name;
}
假设您需要保存 Child
并将他的 ID 发送到某个外部系统。在 DDD 中,您将使用类似于以下的代码保存子项:
AggregateRoot aggregateRoot = aggregateRootRepository.getById(id);
Child child = new Child();
child.setName("Sun");
aggregateRoot.addChild(child);
aggregateRootRepository.save(aggregateRoot);
externalService.postSavedChildId(child.getId());
当然 child.getId()
将 return 为空,因为它不在持久性上下文中。知道应该如何在 DDD 中处理这种情况吗?
Imagine that you need to save Child and to send his ID to the some external system
你做不到。聚合内的实体具有本地身份,这意味着不可能从聚合外部访问这些实体。唯一可从聚合外部访问的实体,即具有全局身份的实体,是聚合根。
因此,您要向外部系统提供其 ID 的实体似乎实际上是聚合根。
还有一个问题,为什么要把一个系统实体的数据库id暴露给另一个系统?系统不应依赖于其他系统的数据库 ID。他们应该改用商家 ID。
你的情况有两个问题,我将分别解决:
- 我们应该如何分发 non-aggregate-root 个实体的 ID?
- 当使用 DB-generated 个 ID 时,我们如何在保存之前获取实体的 ID?
对Non-Aggregate-Root实体的引用
DDD 建议聚合根携带全局 ID,而 "inner" 实体 ID 仅具有局部意义。所以你不应该单独公开内部 ID,因为它不会唯一地寻址实体。
- 拆分两个实体并使内部实体成为其自身的集合。现在它具有全球身份并且可以从外部世界寻址。
- 如果 (1) 在您的域中没有意义,请向外部系统公开组合 ID。您必须能够将组合 ID 分成聚合根 ID 和(本地)内部实体 ID。
DB-Generated ID
由于您遇到的原因,使用 DB-generated ID 不适合 DDD。最好的方法通常是使用生成的随机 ID。
旁注
通过阅读你的问题,我得到的印象是你采取了相当 DB-centric 的方法(使用 DB-generated ID 就是一个迹象)。 使用 DDD 时,首先尝试关注域模型并围绕它构建数据库基础结构。