Oigan si al momento de crear el pageRequest, les sale un error de que tienen que castear el PageRequest a Pageable y este a Page, revisen los imports, muy probablemente tienen alguno como este:

Pero necesitan que todos sean de Spring, como este:

Cuando trabajas con grandes volúmenes de datos en Spring Boot, devolver listas completas no escala. Aquí entra el PagingAndSortingRepository, una variante de los Spring Data Repositories que te permite servir resultados por páginas y ordenarlos sin escribir lógica adicional. Es ideal si construyes APIs que consultan cientos o miles de registros.
Qué es PagingAndSortingRepository y cuándo usarlo
Es un repositorio de Spring Data que extiende las capacidades básicas de CRUD añadiendo paginación y ordenamiento nativo. Lo usas cuando tu endpoint devuelve listas largas y quieres entregar la información en bloques manejables.
¿Qué diferencia hay entre ListCrudRepository y ListPagingAndSortingRepository? El primero solo expone operaciones CRUD básicas y devuelve listas completas. El segundo añade los métodos
findAll(Pageable)yfindAll(Sort)para paginar y ordenar resultados sin escribir queries manuales.
Cómo crear el repositorio paginado
Dentro del paquete repository, creas una nueva interfaz que extienda de ListPagingAndSortingRepository. Le pasas dos tipos genéricos: la entidad y el tipo de su clave primaria.
java public interface PizzaPagSortRepository extends ListPagingAndSortingRepository<PizzaEntity, Integer> { }
Con eso ya tienes acceso al método findAll con dos sobrecargas: una recibe un Sort para ordenar y otra recibe un Pageable para paginar. [02:15]
Cómo modificar el servicio para devolver páginas
En tu PizzaService inyectas el nuevo repositorio y ajustas el método getAll para que reciba dos parámetros: el número de página y la cantidad de elementos por página.
La clave está en construir un objeto PageRequest con el método estático PageRequest.of(page, elements). Este objeto implementa la interfaz Pageable y le indica a Spring qué porción de datos quieres traer.
java public Page<PizzaEntity> getAll(int page, int elements) { Pageable pageRequest = PageRequest.of(page, elements); return pizzaPagSort.findAll(pageRequest); }
Fíjate que el tipo de retorno cambia de List a Page. Esto es importante porque Page no solo trae el contenido, también incluye metadatos como número de página actual, total de elementos y si es la última página.
¿Desde qué número empiezan las páginas en Spring Data? Empiezan desde cero. Si pides la página 0 con tamaño 8, recibirás los primeros 8 registros. La página 1 traería del registro 9 al 16.
Cómo exponer la paginación en el controlador
En el controlador no necesitas inyectar nada nuevo. Solo añades los parámetros page y elements al método y los anotas con @RequestParam. [04:30]
java @GetMapping public Page<PizzaEntity> getAll( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "8") int elements) { return pizzaService.getAll(page, elements); }
Aquí entra una ventaja útil de los RequestParam: puedes definirles un valor por defecto. Si el cliente no envía nada, la respuesta arranca con la página cero y ocho elementos. Así evitas errores y mantienes el endpoint usable sin parámetros explícitos.
Cuál es la diferencia entre RequestParam y PathVariable
Los dos sirven para recibir datos en una petición HTTP, pero viajan distinto. PathVariable forma parte de la ruta misma, como /pizzas/3. RequestParam viaja como query string después del signo de interrogación, como /pizzas?page=0&elements=15.
Esta distinción importa porque los parámetros de paginación no identifican un recurso único, sino que modifican cómo se entrega la colección. Por eso RequestParam es la elección correcta aquí.
Qué información trae el objeto Page en la respuesta
Cuando consultas el endpoint en Postman, la respuesta ya no es una lista plana. Ahora es un objeto JSON con varias secciones útiles:
Si pides page=0&elements=15 y solo tienes 13 pizzas, la respuesta marca last: true porque todo cabe en una sola página. Si pides elements=8, necesitarás dos páginas para cubrir los 13 registros. [07:10]
Por qué la paginación mejora el rendimiento de tu API
Devolver miles de registros en una sola respuesta consume memoria del servidor, ancho de banda y tiempo de renderizado en el cliente. Paginar te permite:
LIMIT y OFFSET.El PagingAndSortingRepository abstrae todo eso y te entrega los metadatos calculados sin que escribas SQL adicional. Es uno de esos casos donde Spring Data te ahorra horas de código repetitivo.
¿Has implementado paginación en tus proyectos? Cuéntame en los comentarios cómo manejas las consultas con muchos registros.
Cuando trabajas con grandes volúmenes de datos en Spring Boot, devolver listas completas no escala. Aquí entra el PagingAndSortingRepository, una variante de los Spring Data Repositories que te permite servir resultados por páginas y ordenarlos sin escribir lógica adicional. Es ideal si construyes APIs que consultan cientos o miles de registros.
Es un repositorio de Spring Data que extiende las capacidades básicas de CRUD añadiendo paginación y ordenamiento nativo. Lo usas cuando tu endpoint devuelve listas largas y quieres entregar la información en bloques manejables.
¿Qué diferencia hay entre ListCrudRepository y ListPagingAndSortingRepository? El primero solo expone operaciones CRUD básicas y devuelve listas completas. El segundo añade los métodos
findAll(Pageable)yfindAll(Sort)para paginar y ordenar resultados sin escribir queries manuales.
Dentro del paquete repository, creas una nueva interfaz que extienda de ListPagingAndSortingRepository. Le pasas dos tipos genéricos: la entidad y el tipo de su clave primaria.
java public interface PizzaPagSortRepository extends ListPagingAndSortingRepository<PizzaEntity, Integer> { }
Con eso ya tienes acceso al método findAll con dos sobrecargas: una recibe un Sort para ordenar y otra recibe un Pageable para paginar. [02:15]
En tu PizzaService inyectas el nuevo repositorio y ajustas el método getAll para que reciba dos parámetros: el número de página y la cantidad de elementos por página.
La clave está en construir un objeto PageRequest con el método estático PageRequest.of(page, elements). Este objeto implementa la interfaz Pageable y le indica a Spring qué porción de datos quieres traer.
java public Page<PizzaEntity> getAll(int page, int elements) { Pageable pageRequest = PageRequest.of(page, elements); return pizzaPagSort.findAll(pageRequest); }
Fíjate que el tipo de retorno cambia de List a Page. Esto es importante porque Page no solo trae el contenido, también incluye metadatos como número de página actual, total de elementos y si es la última página.
¿Desde qué número empiezan las páginas en Spring Data? Empiezan desde cero. Si pides la página 0 con tamaño 8, recibirás los primeros 8 registros. La página 1 traería del registro 9 al 16.
En el controlador no necesitas inyectar nada nuevo. Solo añades los parámetros page y elements al método y los anotas con @RequestParam. [04:30]
java @GetMapping public Page<PizzaEntity> getAll( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "8") int elements) { return pizzaService.getAll(page, elements); }
Aquí entra una ventaja útil de los RequestParam: puedes definirles un valor por defecto. Si el cliente no envía nada, la respuesta arranca con la página cero y ocho elementos. Así evitas errores y mantienes el endpoint usable sin parámetros explícitos.
Los dos sirven para recibir datos en una petición HTTP, pero viajan distinto. PathVariable forma parte de la ruta misma, como /pizzas/3. RequestParam viaja como query string después del signo de interrogación, como /pizzas?page=0&elements=15.
Esta distinción importa porque los parámetros de paginación no identifican un recurso único, sino que modifican cómo se entrega la colección. Por eso RequestParam es la elección correcta aquí.
Cuando consultas el endpoint en Postman, la respuesta ya no es una lista plana. Ahora es un objeto JSON con varias secciones útiles:
Si pides page=0&elements=15 y solo tienes 13 pizzas, la respuesta marca last: true porque todo cabe en una sola página. Si pides elements=8, necesitarás dos páginas para cubrir los 13 registros. [07:10]
Devolver miles de registros en una sola respuesta consume memoria del servidor, ancho de banda y tiempo de renderizado en el cliente. Paginar te permite:
LIMIT y OFFSET.El PagingAndSortingRepository abstrae todo eso y te entrega los metadatos calculados sin que escribas SQL adicional. Es uno de esos casos donde Spring Data te ahorra horas de código repetitivo.
¿Has implementado paginación en tus proyectos? Cuéntame en los comentarios cómo manejas las consultas con muchos registros.
Oigan si al momento de crear el pageRequest, les sale un error de que tienen que castear el PageRequest a Pageable y este a Page, revisen los imports, muy probablemente tienen alguno como este:

Pero necesitan que todos sean de Spring, como este:

Profesor, tengo entendido que si extendiendo directamente del JpaRepository ya obtengo los métodos tanto del ListCrudRepository y ListPagingAndSortingRepository ( y no seria necesario tener que crear otra interfaz ), hay alguna ventaja/contra de hacerlo asi? o es una mala practica? .. Yo siempre suelo extender directamente del JpaRepository ...
Aquella anotación "@RequestParam" no la termino de comprender y al buscar por internet terminé más confundido. ¿Podrían explicarlo más detalladamente?
Es correcto si extiendo ListCrudRepository y ListPagingAndSortingRepository en la misma interface del repository??
Le tenía miedo a Java pero ahora me siento poderoso con esta clase, excelente curso!
Es como el limit y offset pero mas mágico 😅 buenisimo!
En la consola arroja que se hace un select con limit y despues un count
Hibernate: select pe1_0.id_pizza,pe1_0.available,pe1_0.description,pe1_0.name,pe1_0.price,pe1_0.vegan,pe1_0.vegetarian from pizza pe1_0 limit ?,?
Hibernate: select count(pe1_0.id_pizza) from pizza pe1_0
Extender de JpaRepository es una buena práctica, ya que heredas métodos de CrudRepository y PagingAndSortingRepository, lo que te permite realizar operaciones CRUD y paginación sin implementar nada adicional. Usar JpaRepository también te ofrece características avanzadas como la gestión de transacciones y soporte para consultas JPQL y SQL nativas. Si tu proyecto requiere funcionalidad de paginación o consultas más complejas, JpaRepository es la mejor opción.
Si pudiera darle like a una clase sería a esta 😅 lástima que sea tan corta con un tema taaan interesante y tan extenso. Me gustaría un curso de temas así tan específicos como la paginación, que tan necesarios son en el entorno laboral.
Listo ✅