DDD、JPA和非默认构造函数

DDD、JPA和非默认构造函数,jpa,domain-driven-design,Jpa,Domain Driven Design,DDD表示,您的领域模型需要具有表达能力,并说出它们需要什么。考虑到这一点,我创建了以下类: @Entity public class User{ @Id @GeneratedValue private Long id; private String userName; private String password; public User(String userName, String password) { /**set

DDD表示,您的领域模型需要具有表达能力,并说出它们需要什么。考虑到这一点,我创建了以下类:

@Entity
public class User{
    @Id
    @GeneratedValue
    private Long id;

    private String userName;
    private String password;

    public User(String userName, String password) {
        /**set the values*/
    }

    /** Validations, getters and business methods*/
有了这个构造函数,我就知道了构建新用户对象所需的最小值

这种方法的问题在于JPA需要一个无参数的默认构造函数来通过反射来恢复类。在这种情况下,我必须忘记DDD建议,还是有解决办法

在这种情况下,我必须忘记DDD建议,还是有解决办法

这里没有一个好的答案。当我们尝试将对象与可变、封装状态和持久性(即:将状态的权威副本存储在某个贫乏的持久存储中)混合在一起时,会产生一种紧张感

正确的答案是,我们不使用O/RM从持久存储加载域实体;O/RM加载DTO,我们将信息从DTO复制到域对象中。类似地,要保存,可以从域实体提取信息并将其复制到DTO中,然后保存DTO

换句话说,O/RM加载贫血数据结构的内存表示

在实践中,将实体状态与O/RM耦合,在域实体内实现O/RM工作所需的任何接口,这是非常常见的


诀窍是确保当O/RM假设开始阻碍时,可以将实现与O/RM解耦。例如,您应该能够轻松地将特定聚合从使用关系数据存储更改为使用文档数据存储,而无需重写整个系统。

在您的特定情况下,您可以将非参数构造函数设置为私有。但很快,另一个JPA要求将迫使你采取另一种解决办法

voiceofunreason给了你正确的答案。正确的方法是在基础设施/持久性层中有一个适配器,用于接收域对象,然后将其转换为JPA贫血模型,反之亦然

其他一些更适合的选项,无需太多转换:

1-Spring数据JDBC正试图吸收聚合概念

; 2-将聚合持久化为关系数据库中的json。沃恩·弗农提出了一个实施方案->


3-面向文档的数据库,如其他…

使构造函数默认值可见。因此,以正确的方式,我的域对象(由命令对象创建并可以创建查询对象)将生成持久化对象以完成orm操作?我的拼写检查器标记基础结构、接收、贫血,吸收聚集物,在OHER中。