12

根据 DDD,有些类是实体,有些类具有@javax.persistence.Entity注释。他们应该是同一个班级吗?或者 JPA 实体是否应该充当映射器(https://martinfowler.com/eaaCatalog/dataMapper.html)从数据库加载 DDD 实体(并存储它们)并保留在域模型之外的机制?

如果将数据库元数据分离并存储在外部(例如,以 XML 格式),是否会有所不同?如果这些类是实体,那么边界在哪里?我认为从 XSD(例如,使用 JAXB)甚至使用 MyBatis Generator 从数据库生成的类不是 DDD 中所理解的实体。

4

4 回答 4

7

这确实是一个实现细节。它们可能是也可能不是,这取决于您的 ORM 的灵活性。例如,如果您的 ORM 允许映射您的域对象而不会因持久性问题而污染它们,那么这就是需要较少开销的方法,而我会采用这种方法。

另一方面,如果您的 ORM 不够灵活,那么您可以采用实用的混合方法,其中您的 AR 和它的状态是两个不同的类,并且状态类足够简单,可以轻松映射。请注意,AR 仍将负责在此处保护其状态,并且不会从 AR 外部直接访问状态对象。Vaughn Vernon在此处描述了该方法。

于 2017-09-15T20:53:44.803 回答
1

您的 JPA 实体应该是域实体。为什么?您的域实体应该表达一些强约束,例如通过

  • 具有参数化的构造函数
  • 不暴露所有二传手
  • 对写操作进行验证

如果可能,域实体应始终保持有效的业务实体。通过引入某种映射器,您可以将任意内容自动写入域实体中,这基本上会使您的约束变得无用。

另一种选择是对引入冗余的 JPA 和域实体实施相同的约束。

您最好的选择是让您的 JPA 实体尽可能与 ORM 无关。使用 Hibernate,这可以使用配置类或 XML 文件来完成。但我不是 Java EE/JPA 人,所以我很难给出一个好的实现建议。

于 2017-09-15T13:08:23.263 回答
1

在对 JPA 和微服务有更多经验之后,我会说在使用 JPA 时我很可能不会将它们分开,除非有理由让我这样做。另一方面,单个有界上下文中的实体不一定必须是 JPA 实体。可以让 JPA 实现映射实体和使用其他技术(如 JSON 映射器)或手动从 DTO 映射的实体。

于 2019-08-26T21:18:13.020 回答
1

我同意这两种方式都是可能的。在使用 DDD 编写一些应用程序之后,我发现这种启发式方法效果很好:

  • 如果您从拥有一个实体而没有 JPA 开始,那么重构一个实体以使其可以被 ORM 框架使用可能太难了,因此请将它们分开
  • 如果从头开始,不区分 DDD 实体和 JPA 实体是值得的
于 2021-04-13T20:37:24.263 回答