Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which entities do I need to create Spring Data repositories for?

In "getting started" examples of Spring Data JPA, we create an interface which extends CrudRepository. However it handles only one Entity:

import org.springframework.data.repository.CrudRepository;

interface MyEntityRepository extends CrudRepository<MyEntity, Long> {
  // methods...
}

In a real world application, there are many Entities (tables) and we need to do CRUD operations for them. What is the correct way to use Spring Data JPA repositories with multiple (related or unrelated) Entities?

Do I have to create interfaces for each Entities and Autowire them one by one (Which sounds very crazy idea for now)?

like image 592
Yasin Okumuş Avatar asked Sep 08 '15 18:09

Yasin Okumuş


2 Answers

Spring Data use the concept of repositories as defined in Domain Driven Design. Repositories basically represent a collection of aggregate roots, which in turn are some of your entities, that you'll access and which enforce business constraints on others. E.g. if you have an Order consisting of LineItems, the Order'd be the aggregate root as it controls the lifecycle of the LineItems etc. Hence you'd define a repository for the Order but not for the LineItem. So it's by far not all entities that you'd create repositories for. It's basically an important part in your domain modeling to decide which entities become aggregate roots.

Another aspect is that repositories are usually backed by a persistence mechanism and that you don't want to code your business logic directly to the persistence API to keep it testable without having to deal with the persistence API. That means, a repository will contain query methods that basically represent a subset of all aggregate roots in the collection and are backed by a store-specific query implementation. This can only be achieved in a by-aggregate-root fashion.

The third and final aspect is that repositories help you to restrict access to persistence operations more easily as you can use e.g. the package scope to force clients to even use a dedicated service and basically hide all persistence operation for a certain domain object in a certain package. With a generic persistence API like the EntityManager you lose control over who actually reads what from any point in the system as it can just persist each and every type in the persistence context.

To summarize things: repositories represent a collection of aggregates and allow access to dedicated subsets of that collection. Spring Data makes creating these as easy as possible with the alternatives being architecturally less desirable (see reasoning above) or more cumbersome (if they had to be implemented manually. For which entities you create repositories depends on how you model your domain, which of them are aggregate roots.

like image 134
Oliver Drotbohm Avatar answered Oct 22 '22 03:10

Oliver Drotbohm


You are correct. For each entity you want to use Spring Data with, you need to create an interface that extends one of the repository interfaces and then autowire that interface into your classes. You only need one of these per entity you wish to perform crud/query operations on. If there is an entity contained within another entity that is created/managed via a cascade relationship, you don't need to explicitly create a repository for that entity.

To your point, it may seem slightly verbose to have to create an interface and autowire it for each entity, but that's the way Spring Data was designed and is what enables it to automatically generate data access code for you. You obviously wouldn't have to do that if you wanted to write your own data layer.

like image 26
Chris Thompson Avatar answered Oct 22 '22 05:10

Chris Thompson