域对象是不是与 JPA 实体相同?

Posted

技术标签:

【中文标题】域对象是不是与 JPA 实体相同?【英文标题】:Are domain objects the same as JPA entities?域对象是否与 JPA 实体相同? 【发布时间】:2012-05-10 19:13:30 【问题描述】:

域对象是否与 JPA 实体相同?如果我有一个值对象(例如美元钞票),我如何(甚至应该)将它作为引用对象存储在数据存储中?

域对象在某些情况下是实体而在其他情况下是值对象的微妙之处是什么?谁能指导我找到一篇关于这方面的好论文?

【问题讨论】:

是的,域对象与 JPA 实体相同 如果您在域驱动设计环境中,它们就不是,因为域对象往往更健壮而不是“贫血”对象。检查***.com/questions/5589141/… 是什么阻止您将域逻辑放入实体中?这不是首先将表行映射到实际对象的全部意义吗?否则,你也可以只使用 HashMaps 来表示表中一行的数据。 【参考方案1】:

“域对象”是一个更概念化的术语; “JPA 实体”是指用于实现领域对象的特定技术。

通常域对象对应于您域中的名词(订单、发票、客户等)。通常我们认为这些更接近数据库而不是纯粹的数据传输对象。例如,您可能会在用于实现域对象的类上看到 ORM 注释。

很多人以一种贫乏的方式实现域对象——主要是使用 ORM 映射的属性,但域对象本身没有真正的逻辑。他们将逻辑放入域服务中。

另一方面,领域驱动设计的支持者将逻辑放在领域对象上。

无论哪种方式,这些都是您系统中的域对象。

JPA 实体是您使用@Entity、@Column、@ManyToOne 等注释的类。这是实现域对象的一种方式。如上所述,您可以决定将域逻辑放在对象本身上。

【讨论】:

【参考方案2】:

在领域驱动设计的上下文中,它们是不一样的。域对象可以是包含实体和值对象的聚合,并且应该忽略持久性。因此,它不应包含任何 JPA 注释。

【讨论】:

【参考方案3】:

不,域对象是具有丰富行为的对象,代表了相关的业务概念。 JPA 实体是一种持久性的技术解决方案。

【讨论】:

【参考方案4】:

域对象是否与 JPA 实体相同?

不,他们不是。

如果我有一个价值对象(例如一张美元钞票),我如何(甚至应该)将它作为参考对象存储在数据存储中?

我建议使用@Embeddable 存储值对象。 VO 不需要@Id,您应该只从父级引用它们(它们与父级存储在同一个表中)。如果是集合,请使用@ElementCollection。

@Emedded 值对象在 Hibernate 中表现更好:

如果您不使用 @OneToOne,则您没有 JOINS。 值对象集合可以通过一次 DELETE 删除,并且不必在删除前加载。

域对象在某些情况下是实体而在其他情况下是值对象的微妙之处是什么?

实体是由@Id 区分的对象,相反,值对象是由值区分的。值对象通常被实现为不可变的,而实体/域对象包含改变其状态的业务逻辑。

在某些业务案例中,您需要将域对象表示为值对象,也就是快照,例如,您可以将其传递给另一个聚合或在域事件中发布。

谁能指导我找到一篇关于这方面的好论文?

书籍:实施领域驱动设计,Vaughn Vernon。

【讨论】:

以上是关于域对象是不是与 JPA 实体相同?的主要内容,如果未能解决你的问题,请参考以下文章

如果相同的表但不同的模式,如何避免重复 jpa 映射(实体、服务、存储库..)?

在 JPA 中使用相同的实体键映射多个 HashMap

领域驱动设计简介(下篇)

Hibernate - JPA 在不同的情况下生成具有相同名称的重复表

Spring Boot JPA:将一个实体映射到具有相同列的多个(很多)表

在 EntityListener 中使用带有 PersistenceContext 的 EJB 时,JPA 尝试在数据库中插入相同的实体两次