Spring Data Commons und Repository-Abstraktionen
Spring Data Commons definiert gemeinsame Repository-, Mapping-, Auditing- und Paging-Abstraktionen für unterschiedliche Datenstores.
Fachliche Einordnung
Es sorgt dafür, dass JPA, MongoDB, Redis oder JDBC ähnliche Denkmodelle verwenden, ohne die Besonderheiten der einzelnen Stores komplett zu verstecken.
Enterprise-Merksatz: Spring Data Commons definiert gemeinsame Repository-, Mapping-, Auditing- und Paging-Abstraktionen für unterschiedliche Datenstores.
Technische Darstellung
Kernkonzepte
- Repository, CrudRepository, PagingAndSortingRepository.
- Derived Query Methods und explizite @Query.
- Auditing mit @CreatedDate und @LastModifiedDate.
- Domain Events aus Aggregaten.
- Projection und Slice/Page für API-Antworten.
Wann einsetzen?
- Du willst konsistente Datenzugriffe über verschiedene Stores hinweg.
- Du willst Fachlogik vom konkreten Persistence Adapter trennen.
- Du willst Paging, Sorting und Auditing einheitlich behandeln.
Typische Fehler und Risiken
- Repository Interface als Ort für Fachlogik missbrauchen.
- Derived Queries werden unlesbar lang.
- Page direkt als öffentliches API-Vertragsmodell verwenden.
Legacy- und Modernisierungssicht
DAO-Klassen werden häufig in Repository-Adapter überführt; die Fachdomäne sollte aber weiterhin unabhängig von Spring Data Interfaces bleiben.
Ausführliches Beispiel
Das Beispiel zeigt bewusst nicht nur Annotationen, sondern auch die Verantwortung der Schicht. In echten Projekten sollte der technische Spring-Code an Adapter- oder Konfigurationsrändern bleiben, während die Fachlogik testbar und möglichst frameworkarm bleibt.
interface CustomerReadRepository extends Repository<CustomerEntity, UUID> {
Optional<CustomerSummary> findProjectedByCustomerNumber(String customerNumber);
Page<CustomerSummary> findByStatus(CustomerStatus status, Pageable pageable);
}
interface CustomerSummary {
String getCustomerNumber();
String getDisplayName();
CustomerStatus getStatus();
}
@Service
class CustomerDirectory {
private final CustomerReadRepository repository;
CustomerDirectory(CustomerReadRepository repository) { this.repository = repository; }
Page<CustomerSummary> activeCustomers(int page) {
return repository.findByStatus(CustomerStatus.ACTIVE, PageRequest.of(page, 50));
}
}
Checkliste für Reviews
- Ist die Verantwortung des Bausteins klar: Framework steuert Lebenszyklus, Library wird gezielt benutzt?
- Ist die Fachlogik außerhalb von Controller, Listener, Repository-Implementierung oder Konfiguration?
- Sind Fehlerfälle, Timeouts, Security, Monitoring und Tests sichtbar modelliert?
- Gibt es klare Grenzen zwischen DTO, Domäne, Persistence und Infrastruktur?