Home/Learn/Hibernate & JPA/Pagination & Sorting in Spring Data

Pagination & Sorting in Spring Data

Intermediate
Spring Data JPA

Pass Pageable to repository methods; Spring Data returns Page<T> with content, total elements, and page metadata; Sort can be constructed dynamically from user input.

Overview

Spring Data JPA supports pagination and sorting natively. Repository methods accept a Pageable parameter and return Page<T> (includes count query for total elements) or Slice<T> (no count query — cheaper for infinite scroll). PageRequest constructs a Pageable with page number (0-based), page size, and optional Sort. Sort can be constructed dynamically from user-supplied field names but must be validated against a whitelist to prevent SQL injection via field name. For large collections joined with @OneToMany, use @EntityGraph or JOIN FETCH to avoid in-memory pagination warnings (HHH90003004).

Basic Pagination

Extend PagingAndSortingRepository or JpaRepository and add Pageable to any method. Page<T> contains content, totalElements, totalPages, and navigation info.

Java — Page<T> with PageRequest
public interface OrderRepository extends JpaRepository<Order, Long> {

    // Simple paginated query
    Page<Order> findByStatus(String status, Pageable pageable);

    // Paginated with @Query
    @Query("SELECT o FROM Order o WHERE o.customerId = :cid ORDER BY o.createdAt DESC")
    Page<Order> findByCustomer(@Param("cid") Long customerId, Pageable pageable);
}

// Service — page 0, size 20, sort by createdAt descending
Pageable pageable = PageRequest.of(0, 20, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<Order> page = orderRepository.findByStatus("PLACED", pageable);

log.info("Page {}/{}, {} total orders",
    page.getNumber(), page.getTotalPages(), page.getTotalElements());
page.getContent().forEach(o -> process(o));

Slice vs Page — Avoiding the Count Query

Page<T> runs two queries: one for data + one COUNT(*) for totals. For infinite-scroll UIs where you just need hasNext(), use Slice<T> — it runs only the data query.

Java — Slice<T> for infinite scroll (no count query)
public interface ProductRepository extends JpaRepository<Product, Long> {

    // Slice — no count query (cheaper)
    Slice<Product> findByCategory(String category, Pageable pageable);
}

Pageable pageable = PageRequest.of(0, 20, Sort.by("name"));
Slice<Product> slice = productRepository.findByCategory("ELECTRONICS", pageable);

if (slice.hasNext()) {
    // load next page (infinite scroll)
    Pageable next = slice.nextPageable();
}

Dynamic Sort with Whitelist Validation

Never pass user-supplied sort field names directly to Sort.by() — this can expose internal field names or cause injection. Validate against a whitelist map.

Java — whitelist validation for dynamic sort fields
private static final Map<String, String> ALLOWED_SORT_FIELDS = Map.of(
    "name",      "name",
    "price",     "price",
    "createdAt", "createdAt"
);

public Page<Product> search(String sortField, String direction, int page, int size) {
    String safeField = ALLOWED_SORT_FIELDS.getOrDefault(sortField, "createdAt");
    Sort.Direction safeDir = "asc".equalsIgnoreCase(direction)
        ? Sort.Direction.ASC : Sort.Direction.DESC;

    Pageable pageable = PageRequest.of(page, size, Sort.by(safeDir, safeField));
    return productRepository.findAll(pageable);
}

Key Points to Remember

  • 1Page<T> runs two queries (data + COUNT); Slice<T> runs only the data query (use for infinite scroll)
  • 2PageRequest.of(page, size, sort) is 0-based — page 0 is the first page
  • 3Never pass raw user input to Sort.by() — validate against a whitelist first
  • 4JOIN FETCH or @EntityGraph with Pageable causes in-memory pagination — use keyset pagination instead
  • 5Slice.hasNext() checks whether a next page exists without knowing the total count
  • 6Sort.by("field").descending() and Sort.by(Direction, "field") are both valid

Interview Questions

Sign in to ask Aria
1

What is the difference between Page<T> and Slice<T>?

MediumTCS
2

Why is passing user-supplied sort field names to Sort.by() a security risk?

MediumAmazon
3

What page number does PageRequest.of(0, 20) represent?

EasyInfosys
4

What warning does Hibernate produce when you combine JOIN FETCH with Pageable?

HardOracle
5

How would you implement infinite scroll using Spring Data JPA?

MediumFlipkart

Ask Aria about Pagination & Sorting in Spring Data

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…