What is Pageable in Spring Data, and how do you create and use a PageRequest to fetch one page of results?
answer
- PageRequest.of(page, size) — page is 0-based
- Pageable = interface, PageRequest = impl
- last method parameter
- Page adds count query; Slice does not
- Pageable.unpaged() = no limit
basics
~20 sPageable describes which slice to fetch — a page number and a page size. You create one with PageRequest.of(page, size) and pass it to a repository method. Page numbers are 0-based, so page 0 is the first page.
solid answer
~40 sPageable is an interface that carries paging (and optionally sorting) instructions into a Spring Data repository query. The standard implementation is PageRequest, created via the static factory PageRequest.of(pageNumber, pageSize), where pageNumber is zero-based. Overloads accept a Sort or a Direction plus properties. You pass the Pageable as the last parameter of a repository method: List<User> or, more usefully, Page<User> findByActiveTrue(Pageable pageable). Spring translates it into the store's LIMIT/OFFSET (or equivalent). Returning Page<T> also runs a count query so you get total elements and total pages; Slice<T> avoids the count. Use PageRequest.of(0, 20, Sort.by("createdAt").descending()) to combine paging and sorting in one object. Pageable.unpaged() disables paging. Never hand-roll offset math — let PageRequest and next()/previous() navigate.
code
java · 16 linespublic interface UserRepository extends JpaRepository<User, Long> {
Page<User> findByActiveTrue(Pageable pageable);
}
// caller
Pageable firstPage = PageRequest.of(0, 20, Sort.by("createdAt").descending());
Page<User> page = userRepository.findByActiveTrue(firstPage);
long total = page.getTotalElements();
boolean more = page.hasNext();
List<User> rows = page.getContent();
// next page without manual offset math
if (page.hasNext()) {
Page<User> second = userRepository.findByActiveTrue(firstPage.next());
}go deeper
Know PageRequest.of(page, size), that page 0 is first, and pass it as the last method param.
Explain Page vs Slice vs List cost, unpaged(), and combining Sort into the PageRequest.
Discuss count-query cost, deep-offset performance, native-query countQuery, and 0-based mapping pitfalls at the API boundary.
Weigh offset pagination vs keyset/cursor pagination for large datasets and set org-wide list-endpoint conventions (max page size, default sort, count avoidance).
**What problem it solves.** Returning an entire table from a repository method is dangerous — it can load millions of rows into memory. *Pagination* means fetching results in bounded chunks ("pages"). Spring Data models a page request with the `org.springframework.data.domain.Pageable` interface. **Pageable and PageRequest.** `Pageable` is an interface; the concrete implementation you almost always use is `PageRequest`. You never call `new PageRequest(...)` (the constructor is not public in modern versions) — you use the static factory: - `PageRequest.of(int page, int size)` — page is **zero-based** (page 0 is the first page); size is the number of rows per page. - `PageRequest.of(int page, int size, Sort sort)` — page plus a sort order. - `PageRequest.of(int page, int size, Sort.Direction direction, String... properties)` — convenience for a single direction across properties. **How it reaches the query.** You declare the `Pageable` as a method parameter (conventionally the **last** parameter) of a repository method: ```java Page<User> findByActiveTrue(Pageable pageable); ``` Spring Data derives or executes the query and appends the store-specific limiting clause. For JPA/SQL that becomes `LIMIT size OFFSET page*size` (dialect-dependent). The framework computes the offset for you via `pageable.getOffset()` (= `page * size` as a long). **Return types.** The method's return type decides how much extra work happens: - `Page<T>` — the slice **plus** a separate `SELECT count(...)` query, so you get `getTotalElements()` and `getTotalPages()`. - `Slice<T>` — the slice with a `hasNext()` flag but **no** count query (it fetches size+1 rows to know if more exist). - `List<T>` — just the rows, no count, no next flag. **Navigation helpers.** `Pageable` exposes `next()`, `previousOrFirst()`, `first()`, `withPage(n)`, `getPageNumber()`, `getPageSize()`, `getSort()`, `hasPrevious()`. So you rarely do arithmetic yourself. **Unpaged.** `Pageable.unpaged()` returns a special instance meaning "no paging" — the query runs without a limit. `Pageable.unpaged(Sort sort)` (newer versions) applies sorting but no limit. Useful when a method signature requires a `Pageable` but a caller wants everything. **Gotchas.** - The page index is **0-based**, not 1-based — a very common off-by-one bug when mapping from a `?page=1` UI parameter. - `getOffset()` returns a `long`; deep pages produce large offsets and slow OFFSET scans in SQL. - Passing a `Pageable` to a native `@Query` works, but for native queries you often must also supply a matching `countQuery`. - A `Pageable` with no `Sort` gives the database freedom to return rows in **any** order, so page 2 may overlap page 1. Always sort on something deterministic (see the paging-stability question). **When to use.** Any list endpoint that could grow — search results, feeds, admin tables. Prefer `Page` when the UI needs total counts/page numbers; prefer `Slice` for infinite-scroll where a count query is wasteful.
- Why does returning Page<T> instead of List<T> cost more?Page<T> triggers an extra SELECT count(...) query so it can compute getTotalElements()/getTotalPages(). List<T> and Slice<T> skip that count; Slice fetches size+1 rows just to set hasNext().
- A user asks for '?page=1' meaning the first page. What must you do?Subtract 1 — Spring's page index is zero-based, so UI page 1 maps to PageRequest.of(0, size). Forgetting this silently skips the first page of data.
saying these in an interview costs you the question
- Thinking the page index is 1-based
- Believing PageRequest.of always runs a count query regardless of return type
- Computing offset manually instead of using next()/getOffset()
- Assuming results are ordered even without a Sort