JPA实体和DDD实体应该是同一个类吗?

时间:2017-09-14 20:25:51

标签: jpa orm domain-driven-design mybatis mybatis-generator

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

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

4 个答案:

答案 0 :(得分:2)

这真的是一个实现细节。它们可能是或者它们不能取决于ORM的灵活性。例如,如果你的ORM允许映射你的域对象而不用持久性问题来污染它们,那么这就是需要较少开销的方法,而且我需要这样做。

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

答案 1 :(得分:0)

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

  • 有参数化构造函数
  • 不暴露所有制定者
  • 对写入操作进行验证

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

  • 如果您从拥有实体开始而没有 JPA,那么重构实体以供 ORM 框架使用可能会太难,因此请将它们分开
  • 如果你从头开始,不值得区分 DDD 实体和 JPA 实体