gpt4 book ai didi

java - 带有 JPA 的域对象中的注释违反数据库是一个细节

转载 作者:行者123 更新时间:2023-12-04 13:33:49 27 4
gpt4 key购买 nike

您如何看待将持久性模型和域模型分开?我读过您不必将持久性问题与您的业务问题(DDD、Clean Architecture、MartinFowler、Eric Evans 等等)混在一起。即便如此,我仍然在所有项目中看到域模型直接用 ORM 注释进行了注释,域模型与持久性机制耦合,达到了贫血模型并违反了其他原则。

//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class TrainingCycle {
@Id
private Long id;
private String name;

@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT

//EmptyConstructor, getters and setters avoided
}

//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class Discipline {
@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
因此,如果您想遵循干净的原则,您需要拆分域和持久性模型(如下所示)以获得具有业务行为的域模型(这避免贫血模型并遵循 SRP),因此您需要将域模型映射到当您想与 Datastore 交互时使用持久性模型(使用 mapToEntity(DomainModel DM) 和 mapToDomain(PersistenceModel PM) 等典型方法,可能在映射器/转换器中,可能在存储库类中),反之亦然,当您想从数据库中检索数据时。
class Discipline {
private DisciplineId disciplineId;
private String name;

public Discipline(DisciplineId disciplineId, String name) {
this.disciplineId = disciplineId;
this.name = name
}
}

public class TrainingCycle{
private TrainingCycleId trainingCycleId;
private String name;
private DisciplineId disciplineId;

public TrainingCycle(TrainingCyleId trainingCycleId, String name, DisciplineId disciplineId) {
this.trainingCycleId = trainingCycleId;
this.name = name;
assignDiscipline(disciplineId);
}

public void assignDiscipline(DisciplineId aDisicplineId) {
if(aDisicplineId == null) {
throw new IllegalArgumenException("Discipline cannot be null")
}
this.disciplineId = aDisicplineId;
}
}


@Entity
@Table(name="training_cycle")
class TrainingCycleJpa {
@Id
private Long id;
private String name;

@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT

//EmptyConstructor, getters and setters avoided
}


@Entity
@Table(name="training_cycle")
class DisciplineJpa {

@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}

class TrainingCyleJpaRepository implements TrainigCycleRepository {

public void create(TrainingCycle trainingCycle) {
entityManager.persist(this.mapToEntity(trainingCycle)
}

public TrainingCycle create(TrainingCycleId trainingCycleId) {
return this.mapToDomain(entityManager.find(TrainingCycleId));
}
}
所以讨论/问题是从领域模型拆分还是不拆分持久性模型?什么时候分,什么时候不分?在大多数项目中,更不用说在我所看到的所有项目中,我已经看到他们在域模型中对持久性模型进行了注释,而“大师总是在兜售”DataStore 是一个细节。
非常感谢。

最佳答案

请查看这个非常类似问题 :Are persistence annotations in domain objects a bad practice?
我认为作为工程师,我们应该务实。任何最佳实践、原则或“大师建议”都应该有所帮助。他们不应该让事情变得更糟。所以我建议到 将它们视为指导,而不是严格的规则 .例如,我普遍同意“数据库是一个细节”。但我们很少改变那个细节。
另一方面,注解不执行任何代码。而且耦合也没有那么糟糕。您的 域对象可以同时是一个 JPA 实体 ,它将非常干净和有用。顺便说一下,这个不违反单一职责原则 (SPR) .如果您认为是这样,请查看 SOLID explanation by its author Uncle Bob

关于java - 带有 JPA 的域对象中的注释违反数据库是一个细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63393388/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com