java - 创建时 DDD 实体身份生成
问题描述
我的域中有一个实体:
public final class FieldDefinition {
private final FieldDefinitionId id;
private final FieldName name;
//other fields
public FieldDefinition(final FieldDefinitionId id,
final FieldName name) {
checkState(id, name, label, type);
this.id = id;
this.type = type;
}
private void checkState(final FieldDefinitionId id,
final FieldName name) {
Preconditions.checkState(nonNull(id), "id cannot be null");
Preconditions.checkState(nonNull(name), "name cannot be null");
如您所见,创建对象时需要 FieldDefinitionId。此 id 在数据库实体中生成:
@Entity
public final class FieldDefinitionJpaEntity implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
private long id;
@Column(length = 50, nullable = false)
private String name;
....
}
'id' 与 FieldDefinitionId 相同。它是这样映射的:
private FieldDefinition asDomainField(final FieldDefinitionJpaEntity entity) {
return new FieldDefinition(
new FieldDefinitionId(entity.getId()),
new FieldName(entity.getName()),
// other fields
}
现在我从另一个需要保存到数据库的服务接收 FieldDefinitionDto。这是课程
class FieldDefinitionDto {
private final String name;
//other fields
}
如您所见,DTO 对象内没有 id。现在,当我尝试将 DTO 映射到域模型时,我不能这样做,因为需要 FieldDefinitionId。我应该怎么办?我是否应该创建单独的创建模型,例如 FieldDefinitionCreation,它与 FieldDefinition 基本相同但没有 FieldDefinitionId ?我想坚持在数据库级别(而不是使用 UUID 的域级别)生成 id。有人有类似的问题吗?保留 2 个几乎相同的单独模型是个好主意吗?
解决方案
您的 ID 生成策略根本不符合您的域模型设计。
@GeneratedValue(strategy = IDENTITY)
意味着当实体被保存时,身份将由数据库生成。如果您选择此策略,那么您将无法在' 类中创建id
必需的构造函数参数。FieldDefinition
我也有点困惑,为什么您不FieldDefinition
直接使用 JPA 进行映射而不是使用FieldDefinitionJpaEntity
?
无论如何,要么你预先分配一个 ID(仍然可以在数据库中生成),例如
FieldDefinitionId id = fieldDefinitionRepository.nextId();
FieldDefinition fd = new FieldDefinition(id, name);
或者您在持久化时使用生成的 ID,例如
FieldDefinition fd = new FieldDefinition(name); //no ID yet
fieldDefinitionRepository.save(fd); //ID assigned
我总是更喜欢预先生成 ID,因为它更容易生成域事件等。
推荐阅读
- c# - 如何使 2d 对象不断向一个方向移动,但是当给定水平输入改变方向但不改变速度时?
- tcp - 哪个IP地址有效或无效
- matlab - 如何使用 tiledlayout 生成未对齐的子图?
- angular - 在组件中使用 Angular Observable 订阅值
- powershell - PowerShell:从属性-lt X的对象集合中选择行
- javascript - 我想使用反应以 3*X 的网格方式显示图像
- javascript - 如何用数组替换 vuejs 中的插槽?
- http - Cookie 未保存在 Microsoft Edge 中
- r - 使用 devtools::install_local 构建小插图 - 在一个小插图中创建的全局变量在另一个小插图中可用
- java - 将单词添加到 StringBuffer