从域对象到 JPA 实体的映射:如何正确获取关联实体?

问题描述 投票:0回答:1

我在我的应用程序中遵循 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();
    } 
}

我的问题是:

  1. 如何实现从
    Employee
    EmployeeEntity
    的映射?

选项A:我是否首先从数据库中获取

PositionEntity
以满足其与
EmployeeEntity
的关系?在这种情况下,映射器类中将需要
PositionJpaRepository

选项B:

positionId
中只有
EmployeeEntity
,无需接收整个
PositionEntity

2. 如果我选择选项 A,会影响我的应用程序的性能吗?

database spring-boot hibernate jpa hibernate-mapping
1个回答
0
投票

正如 @akuma8 所建议的,这取决于您需要如何处理

Employee
数据,无论是在 REST 响应中返回它,还是在
POST
或其他可能保存或更新实体的调用中获取它数据库。

如果您选择在

Position
类中使用完整的
PositionEntity
(即
Employee
的域对象),在读取数据时,您将始终拥有映射器来完全转换域对应项中的实体,并且这数据将始终传输到客户端,即使客户端可能对
position
信息不感兴趣。在数据写入时,调用者必须在请求正文中返回
position
(或者至少是它的
id
)。在这种情况下,您可能会考虑向实体添加一些
CASCADE
逻辑。

相反,选择仅使用域对象中的

id
来管理属性,不会总是返回完整信息(即使它总是从数据库中获取,除非您选择延迟加载而不是急切加载)一),并且您可以使用
JpaRepository
getReferenceById
方法相应地填充实体的
position
属性,而无需进一步调用数据库(与调用
findById
时发生的情况不同)。 当然,在这种情况下,您将需要一个额外的端点来让客户端获取和更新
Position
信息(鉴于其
id
),这可能会增加一些开销。

特别针对这种情况,由于存在

@OneToOne
关系,因此两个对象在逻辑上是耦合的,如果不会发生,
position
id 可能会更改为另一条记录,就像在
@ManyToOne
中发生的那样例如,完整的映射(因此,选项 A)可能是最好的关系。

© www.soinside.com 2019 - 2024. All rights reserved.