领域驱动设计的存储库和Spring Data存储库之间存在不匹配吗?

18

DDD规定每个聚合应有一个仓储(repository),但是当使用Spring Data JPA时,我们只能在声明每个实体的接口之后才能利用其优势。如何解决这种阻抗不匹配问题?

我希望尝试将存储库接口封装在聚合存储库中,这是可行的解决方案吗?还有更好的选择吗?

Customer 为聚合根,实体类如 DemographicsIdentificationAssetSummary 等都有自己的存储库接口。最佳方法是什么,而且不能违反DDD的规定?


几乎重复:https://dev59.com/j2Ei5IYBdhLWcg3wd8AF - Jens Schauder
1个回答

22
当使用Spring Data JPA时,我们只有在每个实体声明接口时才能利用其优势。这是错误的,我想知道您是从哪里得到这种印象的(请随意评论)。 Spring Data存储库期望与您的域模型设计完全相同的方法:您在域模型中识别聚合,并仅为这些聚合创建存储库接口。我认为,您需要做的就是将DDD概念应用于您的域模型。简单地说,不要为不是聚合根的实体声明存储库接口。事实上,如果您声明了这些内容,您基本上会破坏聚合的概念,因为实际根无法通过为其他实体定义的存储库接口控制业务约束,即可以通过这些接口操作其他实体而不使用聚合根。
Spring Data example中可以找到正确应用的示例。其中,Order是聚合根,LineItem只是普通实体。同样适用于Customer(根)和Address(普通实体)。仓库接口仅存在于聚合根中。
事实上,这种特定关系是使Spring Data REST等模块首先工作的基本原则。它仅为聚合根公开HTTP资源,在创建表示时嵌入普通实体,并创建指向其他聚合的链接。

感谢您的回答。我在考虑将实体作为聚合的一部分,而这个实体不需要与聚合根进行关系映射时,产生了这个问题。我猜想可以通过自定义聚合根的存储库实现这一点,我的假设是错误的吗? - Somasundaram Sekar
进一步说,当我不得不使用这种自定义实现时,我或多或少地开始放弃Spring Data的好处(如果我上面所述的假设成立)。 - Somasundaram Sekar
4
当一个实体不包含在另一个聚合中时,它也可以有自己的存储库。我通常将其视为具有该实体作为聚合根的单个实体聚合。该模式的重要部分是,在聚合中包含的实体必须仅通过聚合进行操作。因此,并非每个JPA实体都需要在其旁边有Spring Data存储库。 - Oliver Drotbohm
完全相同的方法?真的吗?你有试过设计一个值对象吗?没有 @Id 持久化一个对象并不容易,无论你添加多少接口。当然,我们可以将它们嵌入其中,但这并不能代表模型。大多数都是另一个对象的从属物,但并不被其封装...绝对不在另一个对象的范围内定义。在我看来,最好给它们一个身份。至少这不会减慢数据库的速度。 - Nate T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接