Repositories

Basic Spring
≈ 2 min read

A repository as the data-access boundary

If a service needs to save a customer or find one by identifier, it does not have to know how SQL is created or how a query result becomes an object. That responsibility can be moved into a repository — a dedicated data-access interface.

interface CustomerRepository extends CrudRepository<Customer, Long> {
}

@Service
class CustomerService {
    private final CustomerRepository repository;

    CustomerService(CustomerRepository repository) {
        this.repository = repository;
    }

    Customer find(long id) {
        return repository.findById(id).orElseThrow();
    }
}

We declared only an interface. Spring Data JDBC creates the implementation of typical operations, and the repository itself becomes a regular Spring bean that can be injected through a constructor. The first generic parameter specifies the entity type, and the second specifies the identifier type.

What should stay outside the repository

A repository is responsible for data access, not for the entire business scenario. For example, the rule “the last administrator cannot be deactivated” belongs to application logic, so it is a better fit for a service. The repository can provide the required data or write operation, but it should not become a container for all business logic.

A repository interface is a contract of your code. The fact that Spring creates the implementation does not prevent the application from depending on a clear and small data-access API.