Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD, domain entities/VO and JPA

I'm starting with DDD and you can image my brain is boiling.

My question is related to my domain objects (entities, VO, ...) which represents my domain concepts/logic and how to persist/retrieve them.

The blue book says the repository is a way to represent collections on domain objects and is responsible to communicate with the infrastructure layer. I read also at some post the infrastructura layer is where you must use hibernate, JPA or whatever.

Then I see this Spring-data-jpa example http://spring.io/guides/gs/accessing-data-jpa/ and I become crazy.

The slogan say Spring-data-jpa is to create repositories easily and the previous samples seems to merge JPA annotations into a domain object (the customer).

Is the sample right? or Am I right?

If I'm right and the domain and infrastructure must be separated, that means to store a customer I must have:

  • a Customer class in my domain layer (that represents a customer and has all the logic operations)
  • a CustomerRepository un my domain layer (that retrieves or stores customers from infrastructure layer)
  • a Customer class in infrastructure layer, probably annotated with @Entity
  • Some CustomerReposityJPA that know how to store/retrieve customers from database.

Thanks for any clarification.

like image 670
acanimal Avatar asked Jul 14 '15 07:07

acanimal


People also ask

What are entities and Vos in DDD?

Entities and VOs are two of the building blocks in DDD expressing the model. They are the starting points for Domain-Driven Design (besides Services and Domain Events). Besides just looking at the definitions of Entity and VO, I will also provide you with some guidance on how to distinguish them.

How should domain entities be persisted in plain DDD?

One represents business rules, other is easy to persist and query. If it was just single model, it would be necessary to make tradeoff-s between the two. This is specific way to implement DDD. In plain DDD, there is nothing that talks about how the domain entities should be persisted. It is considered a secondary concern.

Should a repository work with domain entities or persistence entities?

That means that the repository should work with domain entities, not persistence entities. But that is what is happening here. Transformation from domain to persistence entities happens in services, which is wrong place to do it. It should happen inside the repositories. This way, it becomes implementation detail of a repository.

What is an entity and value type in DDD?

In Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans, Entity and Value Types are 2 of the fundamental building blocks that the concepts in the rest of the book are built on. Let’s take a look at what they are and why they matter. In DDD, an Entity is something that has an identifier and an owner.


2 Answers

In DDD, a repository is an object that participates in the domain but really abstracts away some backing store.

If you annotate your domain objects with JPA annotations, your persistence mechanism has bled into your domain. You have tied your domain structure to your persistence structure which is not ideal.

Your JpaCustomerRepository (implements ICustomerRepository) could map the unannotated domain classes (Customer) into an annotated JPA representation - JPA customer. This keeps the annotations out of your domain classes, so is cleaner. It allows you to vary the JPA persistence structure independently of your domain structure. The cost for this benefit is the complexity of the mapping code.

interface ICustomerRepository {}

class JpaCustomerRepository implements ICustomerRepository {
     void save(Customer customer) {
          JpaCustomer jpaCustomer = map(customer);
          save(jpaCustomer);
     }
}

class Customer {}

class JpaCustomer {}
like image 71
Tom Hughes Avatar answered Oct 21 '22 21:10

Tom Hughes


I can't see the link you've posted and I have never apply Domain driven design to the Java world. Theoretically what you need is Customer aggregate in the domain layer. In your domain layer there's space for the repository (intended as interface), so you'll have ICustomerRepository. Probably you will have the four prototype for the common persistence issues:

GetById(CustomerId id);
Add(Customer c);
Delete(Customer c);
Update(Customer c);

In the infrastructure layer you will provide the body (for instance CustomerRepository), in the infrastracture layer you can couple yourself with something technological (for example JPA).

Domain layer MUST be completly unaware of technology used in the infrastructure. Doing so you could change completly the implementation details having (almost) no troubles.

like image 21
BAD_SEED Avatar answered Oct 21 '22 22:10

BAD_SEED