Is there a mismatch between Domain-Driven Design repositories and Spring Data ones?
Asked Answered
S

1

18

DDD specifies repository per aggregate, but when embracing Spring Data JPA, we can leverage the benefits only when we declare interface per entity. How this impedance mismatch can be resolved?

I'm hoping to try out repository interfaces encapsulated within the aggregate repository, is that a OK solution or anything better available?

To given an example: Customer is the aggregate root and entities are like Demographics, Identification, AssetSummary etc. where each entity can benefit from having their own repository interfaces. What is the best way without violating DDD much?

Semmes answered 23/7, 2016 at 6:11 Comment(1)
Almost duplicate: #21265762Thermistor
C
22

…, but when embracing Spring Data JPA, we can leverage the benefits only when we declare interface per entity…

That's wrong and I would like to learn where you get this impression from (feel free to comment). Spring Data repositories are expecting the exactly same approach to your domain model design: you identify aggregates in your domain model and only create repository interfaces for exactly those.

I'd argue that all you need to do is applying the DDD concept to your domain model. Simply don't declare repository interfaces for entities that are not an aggregate root. In fact, if you declared those, you basically break the concept of an aggregate, as the actual root cannot control business constraints anymore as the other entities can be manipulated through the repository interface defined for them, i.e. without using the aggregate root.

Find an example of this applied correctly in this Spring Data example. In it, Order is an aggregate root, LineItem is just an ordinary entity. The same applies to Customer (root) and Address (ordinary entity). Repository interfaces only exist for the aggregate roots.

In fact, that particular relationship is the fundamental principle that makes modules like Spring Data REST working in the first place. It only exposes HTTP resources for aggregate roots, embeds ordinary entities within the representations created and creates links to other aggregates.

Cadaver answered 23/7, 2016 at 13:45 Comment(4)
Thanks for your answer. The question occurred to me while trying to consider the possibility of having an entity as a part of an aggregate which doesn't or needn't having relational mapping to the aggregate root, I guess t this can be achieved thro custom repository impl for aggregate root, am I wrong assuming this?Semmes
Further when I have to go with such custom impl, I more or less start to forego the benefits of Spring Data (if my assumption stated above holds)Semmes
Entities that are not contained in another aggregate can of course get their repository, too. I usually think of them as a single-entity aggregate with the entity being the aggregate root itself. The important part of that pattern is that entities contained in an aggregate must not be manipulated except through the aggregate. Hence, not every JPA entity gets a Spring Data repository at its side.Cadaver
The exact same approach? Really? Ever tried to design a value object. Its not so easy persisting an object without an \@Id, no matter how many interfaces you add. Sure, we can embed them, but that doesnt represent the model. Most are dependants of another obj, but not encapsulated by them... Definitely not defined within the scope of another obj. Imo it is better to give them identity. At least this doesn't slow down the DB.Caucasoid

© 2022 - 2024 — McMap. All rights reserved.