在正确的 CQRS 实现中,命令可以包含数据库实体吗?

In a correctly CQRS implementation, can a Command contain a DB Entity?

我还在研究这种模式(即 CQRS),我的一个同事开始在我们的小项目中实现它,但坦率地说,我对它的实现确实有些怀疑。

对于初学者,我们没有使用任何特定的框架,而是在 Java 中使用 Spring Boot 进行开发(但这个问题不是特定于编程语言的)。另一件你可能会觉得很奇怪的事情是模式还没有完全实现,只有命令和查询分离概念(没有事件,没有聚合,没有真正的总线)。

那么让我们看看我们用自下而上的方法做了什么:

我不想深入了解我们的实现,因为我只想知道以下命令是否可行。

@Data // Lombok annotation
@Entity
class User {
    @Id private Long id;
    private String firstName;
    private String lastName;
    private Integer age;
}

@Value
class EditUserCommand {
    private final User user;
}

@Service
class EditUserCommandHandler extends CommandHandler<EditUserCommand> {
    @Inject
    private UserRepository users;

    @Override
    public void handle(final EditUserCommand command) {
        User old = this.users.findOne(command.getUser().getId());
        User current = command.getUser();
        current.setId(old.getId());

        current = this.users.save(current); 
    }
}

这就是我们在项目中实现模式(或者更确切地说是 C&Q 分离概念)的方式……但坦率地说?我不知道它是否正确,我发现代码对于 CQRS 模式来说非常不合常规。我的问题是:

提前感谢您的回复。

你是对的。该命令应仅包含执行实际工作所需的最少信息(在 ModifyUserAgeCommand 的情况下,它只能包含用户 ID 和新年龄)。在您的处理程序中,您的存储库应该负责从数据库中重新水合模型,并且您应用命令中包含的信息中适用的任何更改并保留在存储库中。如果您使用的是 DDD,请使用负责用户的聚合来应用更改并保留。

顺便说一句,只要您使用单独的 类 和模型来处理读取(查询)和写入(命令),它仍然是 CQRS。 CQRS 必须包括事件溯源、最终一致性、DDD……恕我直言,它恰好适用于这些模式,这通常是一种误解。