Let’s break down the difference between CrudRepository
, PagingAndSortingRepository
, and JpaRepository
clearly — because they are related but not identical.
🧩 1. Common Ground
All three are interfaces provided by Spring Data JPA to abstract database operations.
They are hierarchically related, meaning:
JpaRepository ⟶ PagingAndSortingRepository ⟶ CrudRepository
So each higher interface extends the previous one and adds more features.
🔹 2. CrudRepository
Basic interface for CRUD operations.
public interface CrudRepository<T, ID> extends Repository<T, ID> { ... }
✅ Provides:
- Create, Read, Update, Delete methods.
🔧 Common methods:
<S extends T> S save(S entity);
Optional<T> findById(ID id);
Iterable<T> findAll();
void deleteById(ID id);
void deleteAll();
boolean existsById(ID id);
long count();
💡 Use When:
You just need basic CRUD operations — no pagination, no sorting, no JPA-specific features.
📘 Example:
public interface UserRepository extends CrudRepository<User, Long> {}
🔹 3. PagingAndSortingRepository
Adds pagination and sorting on top of CrudRepository
.
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { ... }
✅ Adds:
Methods for sorting and pagination.
🔧 Common methods:
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
💡 Use When:
You need to fetch data in pages or sort results easily.
📘 Example:
public interface UserRepository extends PagingAndSortingRepository<User, Long> {}
Usage:
Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
Page<User> page = userRepository.findAll(pageable);
🔹 4. JpaRepository
Extends everything above + adds JPA-specific features.
public interface JpaRepository<T, ID>
extends PagingAndSortingRepository<T, ID> { ... }
✅ Adds:
More advanced JPA operations like:
- Batch operations
- Flushing persistence context
- Deleting in bulk
- Working with persistence context (
EntityManager
)
🔧 Common methods:
List<T> findAll();
List<T> findAllById(Iterable<ID> ids);
void flush();
<S extends T> S saveAndFlush(S entity);
void deleteInBatch(Iterable<T> entities);
💡 Use When:
You want full JPA capabilities, such as:
- Integration with Hibernate session
- Batch inserts/updates
EntityManager
features
📘 Example:
public interface UserRepository extends JpaRepository<User, Long> {}
🧱 5. Hierarchy Diagram
Repository
│
└── CrudRepository
│
└── PagingAndSortingRepository
│
└── JpaRepository
So:
JpaRepository
⊃PagingAndSortingRepository
⊃CrudRepository
Each layer adds features on top of the previous.
⚖️ 6. Comparison Table
Feature | CrudRepository | PagingAndSortingRepository | JpaRepository |
---|---|---|---|
Basic CRUD | ✅ | ✅ | ✅ |
Pagination | ❌ | ✅ | ✅ |
Sorting | ❌ | ✅ | ✅ |
JPA-specific methods (flush, batch, etc.) | ❌ | ❌ | ✅ |
Return type List instead of Iterable | ❌ | ❌ | ✅ |
Recommended for | Simple CRUD | Pagination/sorting needs | Full JPA use (most common) |
✅ In Practice
👉 In most Spring Boot projects, developers use JpaRepository
because:
- It includes everything in the others.
- It’s the most flexible and convenient.
- Works seamlessly with Hibernate and Spring Data JPA features.
💡 Summary:
Interface | Level | Use Case |
---|---|---|
CrudRepository | Basic | Minimal CRUD operations |
PagingAndSortingRepository | Intermediate | CRUD + pagination + sorting |
JpaRepository | Advanced | Full JPA functionality (recommended for most apps) |