Repository Abstractions
About
In a typical Java application, if we want to interact with a database (e.g., fetch, insert, update records), we would traditionally:
Write a DAO (Data Access Object) class manually
Inject an
EntityManager
Manually create queries and handle exceptions
Spring Data JPA abstracts all that by providing a Repository Layer.
Repository Abstraction means:
Hiding the complexity of data access layers through ready-made interfaces, while still providing flexibility for customization.
Instead of writing SQL/JPQL and managing EntityManager
code manually, we just define interfaces - Spring Data JPA takes care of the rest.
Evolution of Repository Abstractions
DAO Pattern
You create classes to manage database operations manually (classic way).
JPA EntityManager
Java EE way to persist entities with EntityManager.
Spring Data Repositories
Modern abstraction: You only define interfaces; implementation is created automatically.
Spring Data JPA builds a high-level abstraction on top of JPA and EntityManager.
Core Repository Interfaces in Spring Data
Spring Data JPA provides several base interfaces that we can extend:
Repository<T, ID>
Base marker interface — No methods, just identifies a repository.
CrudRepository<T, ID>
Provides basic CRUD methods like save
, findById
, findAll
, delete
.
PagingAndSortingRepository<T, ID>
Extends CrudRepository
and adds pagination and sorting capabilities.
JpaRepository<T, ID>
Extends PagingAndSortingRepository
; adds JPA-specific methods like flush()
, saveAll()
, deleteInBatch()
.
QueryByExampleExecutor<T>
Allows query creation using Example (probe object) for dynamic search.
1. Repository<T, ID>
Repository<T, ID>
Pure marker interface — does not declare any method.
Purpose: Identify the type as a Repository for Spring Data to pick up.
2. CrudRepository<T, ID>
CrudRepository<T, ID>
Provides basic CRUD operations:
save(S entity)
Save an entity.
findById(ID id)
Find an entity by its ID.
findAll()
Fetch all entities.
delete(T entity)
Delete an entity.
existsById(ID id)
Check if entity exists.
count()
Get count of entities.
3. PagingAndSortingRepository<T, ID>
PagingAndSortingRepository<T, ID>
Extends
CrudRepository
.Adds pagination and sorting capabilities.
findAll(Pageable pageable)
Fetch paginated data.
findAll(Sort sort)
Fetch sorted data.
4. JpaRepository<T, ID>
JpaRepository<T, ID>
Extends
PagingAndSortingRepository
.Adds JPA-specific optimizations like:
flush()
Synchronizes persistence context to the database immediately.
saveAll(Iterable<S> entities)
Batch save entities.
deleteInBatch(Iterable<T> entities)
Batch delete.
findAllById(Iterable<ID> ids)
Find all entities matching IDs.
Most real-world applications extend JpaRepository
.
5. QueryByExampleExecutor<T>
QueryByExampleExecutor<T>
Allows building queries using Example Matching instead of manual query methods.
Example:
No need to define explicit query methods.
How Repository Abstractions Work Internally ?
Spring Data JPA creates dynamic proxies for the repository interfaces.
Proxies interpret method names to generate SQL/JPQL automatically.
If we add
@Query
, it directly executes the provided query.The proxy uses injected EntityManager to perform all operations.
Customizing Repositories
If default behavior isn't enough:
We can write custom methods manually (Custom Repository Implementation).
Or override default methods.
Then:
Last updated
Was this helpful?