我在我的应用程序中遵循 DDD,我想将我的持久层与域层分开。 我必须将 Domain 对象映射到 JPA 实体以实现持久性。
我有一个名为
Employee
的域聚合,具有 positionId
作为属性。在持久层中,我同时使用 JPA @Entity 注释标记了 EmployeeEntity
和 PositionEntity
,如下所示:
@Entity
public class EmployeeEntity {
@Id
private String employeeId;
//other properties
@OneToOne
@JoinColumn(name = "position_id")
private PositionEntity position;
}
@Entity
public class PositionEntity {
@Id
private String position_id;
//other properties
@OneToOne(mappedBy = "position")
private EmployeeEntity employee;
}
public class EmployeeDataAccessMapper {
public EmployeeEntity employeeToEmployeeEntity(Employee employee) {
return EmployeeEntity.builder().
//get and set all properties
.build();
}
}
我的问题是:
Employee
到EmployeeEntity
的映射?选项A:我是否首先从数据库中获取
PositionEntity
以满足其与EmployeeEntity
的关系?在这种情况下,映射器类中将需要 PositionJpaRepository
。
选项B:
positionId
中只有EmployeeEntity
,无需接收整个PositionEntity
。
2. 如果我选择选项 A,会影响我的应用程序的性能吗?
正如 @akuma8 所建议的,这取决于您需要如何处理
Employee
数据,无论是在 REST 响应中返回它,还是在 POST
或其他可能保存或更新实体的调用中获取它数据库。
如果您选择在
Position
类中使用完整的 PositionEntity
(即 Employee
的域对象),在读取数据时,您将始终拥有映射器来完全转换域对应项中的实体,并且这数据将始终传输到客户端,即使客户端可能对 position
信息不感兴趣。在数据写入时,调用者必须在请求正文中返回 position
(或者至少是它的 id
)。在这种情况下,您可能会考虑向实体添加一些 CASCADE
逻辑。
相反,选择仅使用域对象中的
id
来管理属性,不会总是返回完整信息(即使它总是从数据库中获取,除非您选择延迟加载而不是急切加载)一),并且您可以使用 JpaRepository
的 getReferenceById
方法相应地填充实体的 position
属性,而无需进一步调用数据库(与调用 findById
时发生的情况不同)。
当然,在这种情况下,您将需要一个额外的端点来让客户端获取和更新 Position
信息(鉴于其 id
),这可能会增加一些开销。
特别针对这种情况,由于存在
@OneToOne
关系,因此两个对象在逻辑上是耦合的,如果不会发生,position
id 可能会更改为另一条记录,就像在 @ManyToOne
中发生的那样例如,完整的映射(因此,选项 A)可能是最好的关系。