Changelog¶
All notable changes to easy-paging are documented here. The format is based on Keep a Changelog, and the project follows Semantic Versioning.
For the canonical, machine-readable source see CHANGELOG.md in the repository.
[4.0.0] — 2026-05-23¶
Renumbering of 0.5.0 per the new Spring-major-aligned versioning policy. No API, behaviour, or dependency changes — the major number bumps from 0.5 to 4.0 to match the Spring Boot major (Spring Boot 4) this line targets. Published JAR bytes are identical to 0.5.0 apart from the version coordinate in the POM.
Going forward, all Spring Boot 4 releases of this starter ship on the 4.x.y line. The Spring Boot 3 line is renumbered to 3.x.y in the same wave (0.4.0 → 3.0.0). The previous 0.4.0 / 0.5.0 artifacts remain on Maven Central as historical references.
Upgrading from 0.5.0¶
- implementation("kr.devslab:easy-paging-spring-boot-starter:0.5.0")
+ implementation("kr.devslab:easy-paging-spring-boot-starter:4.0.0")
- implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0")
+ implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:4.0.0")
No other changes. Same Spring Boot 4 baseline, same MyBatis 4.0.1 / PageHelper 4.0.0, same APIs.
[0.5.0] — 2026-05-23¶
Spring Boot 4 release line. First cut of the 0.5.x line targeting Spring Boot 4 / Spring Framework 7 / Jackson 3. The 0.4.x branch continues as the Spring Boot 3.3–3.5 maintenance line and still receives security patches.
Changed¶
- Spring Boot baseline raised to 4.0+ (built/tested against
4.0.6). Pulls in Spring Framework 7, Jakarta EE 11, Jackson 3, and Servlet 6.1. - PageHelper bumped
2.1.1→4.0.0(its first SB4-compatible release), which transitively bringsmybatis-spring-boot-starter3.0.4→4.0.1. The starter now also pins4.0.1directly for conflict-resolution stability. spring-boot-starter-aoprenamed tospring-boot-starter-aspectjin SB4. Same artifact contents, new ID — followed.io.spring.dependency-managementbumped1.1.6→1.1.7(SB4-compatible).@Nullableswitched fromorg.springframework.lang.Nullable(deprecated in Spring 7) toorg.jspecify.annotations.Nullable.- Jackson 2 → 3 migration — imports moved from
com.fasterxml.jackson.*totools.jackson.*;JsonProcessingException→JacksonException;JavaTimeModuleis auto-registered (no explicit registration needed). - Starter auto-registers
PageableHandlerMethodArgumentResolver+SortHandlerMethodArgumentResolveritself (servlet MVC), plus the reactive equivalents for WebFlux. SB4 dropped the auto-config that previously did this for MVC; apps no longer need a per-appWebMvcConfigurer/WebFluxConfigurerto usePageable pageablecontroller parameters. ExistingPageableHandlerMethodArgumentResolverCustomizerbeans (e.g.easy-paging.one-indexed-pages=true) are still honored.
Migration notes¶
Coming from 0.4.x:
- Bump Spring Boot to 4.x + this starter to
0.5.xtogether. - Bump the dependency-management plugin to
1.1.7. - Bump Gradle wrapper to 8.14+ (the SB4 plugin refuses older Gradle).
- If your tests use
@AutoConfigureMockMvcor@AutoConfigureWebTestClient, the imports moved to dedicatedspring-boot-starter-{webmvc,webflux}-testmodules. - If your tests use Testcontainers, 2.x renamed module artifacts (
postgresql→testcontainers-postgresql, etc.) and moved*Containerclasses into dedicated per-module packages.
Staying on Spring Boot 3.3–3.5? Use the 3.x maintenance branch (3.0.0).
[0.4.0] — 2026-05-20¶
Added¶
- New optional artifact
easy-paging-spring-boot-starter-reactive— native R2DBC + WebFlux support, sibling to the core starter. Existing MyBatis users add nothing; the new starter is purely additive. Three pieces ship:R2dbcOffsetPagingSupport.paginate(template, entity, criteria, pageable)— page rows + count query parallelized viaMono.zip, produces the samePageResponseenvelope as the MyBatis side.R2dbcKeysetSupport.paginate(template, entity, baseFilter, keys, request, keyExtractor, codec)— keyset/cursor pagination on R2DBC, with built-in type coercion forInstant,LocalDateTime,OffsetDateTime,LocalDate,UUID, and primitive wrappers.ReactiveKeysetRequestArgumentResolver— WebFlux counterpart of the servletKeysetRequestArgumentResolver. Auto-registered when WebFlux is on the classpath.
PageResponse.of(rows, pageable, total)— new core factory for the "known total" case (the typical R2DBC pattern). ComplementsPageResponse.from(list, pageable)which infers the total from a PageHelper-wrapped list.- Dialect-compat test layer — new
./gradlew testDialecttask runs@Tag("dialect-compat")tests against real PostgreSQL + MySQL via Testcontainers, on top of the existing fast H2 path. Catches the PageHelper dialect-rewriting paths and R2DBC type-binding behavior that H2 doesn't exercise.
Changed¶
- Gradle build migrated to multi-module structure (
core/+reactive/). The publishedkr.devslab:easy-paging-spring-boot-startercoordinates are byte-identical; users only need to add the new…-reactiveline if they want the R2DBC stack. - CI / release workflow paths updated for the multi-module layout; release asset glob now
**/build/libs/*.jarso future module jars attach automatically.
Notes¶
- Strictly additive for existing v0.3 consumers — adding
easy-paging-spring-boot-starter-reactiveis opt-in; the core artifact's coordinates and behavior are unchanged. - The new reactive auto-configurations gate themselves on
@ConditionalOnClass(ServerWebExchange.class)etc., so dead code doesn't run when WebFlux / R2DBC aren't on the consumer's classpath.
[0.3.0] — 2026-05-18¶
Added¶
- Keyset reverse direction.
KeysetPage.prevCursoris no longer alwaysnull— it's populated whenever a page that isn't the first is returned, encoded withBACKWARDdirection. Cursor field semantics are direction-invariant:nextCursoralways means "load older items",prevCursoralways means "load newer items". The client never has to track which way they're scanning. See Bidirectional scrolling for the consumer-side pattern (mirrorfindBeforemapper +request.direction()dispatch).
Changed¶
- Spring Boot baseline bumped 3.3.5 → 3.5.3. Internal build/test baseline only; consumers on Spring Boot 3.3+ continue to work because our Spring deps are declared via
api(...)without version pinning. 3.3 and 3.4 reached OSS end-of-life before this release, so 3.5 is the only currently OSS-supported line. - PageHelper bumped 2.1.0 → 2.1.1. Picks up MyBatis 3.5.19 + PageHelper engine 6.1.1 (upstream bug-fix patches).
mybatis-spring-boot-starter:3.0.4is now provided transitively — consumers no longer have to add it themselves. Previously, PageHelper's transitive Spring Boot 2.7 line MyBatis starter could leak into apps that forgot to override it; now the library pins the Boot 3-compatible version directly. Override viaexclude(group = "org.mybatis.spring.boot")if you need a different MyBatis line.- Docs:
installationpages updated to reflect both dependency changes;keysetguide gains the "Bidirectional scrolling" section.
Notes¶
KeysetPage.buildAPI signature is unchanged, but its behavior is now direction-aware. Forward-only consumers see no change; the only observable difference is thatprevCursoris no longer alwaysnullon pages past the first.- JUnit Jupiter 5.11+ (shipped by Spring Boot 3.5) needs an explicit
junit-platform-launcherdeclaration in projects on Gradle 8.10.x. Build-only concern for this library; not exposed to consumers.
[0.2.0] — 2026-05-18¶
Added¶
easy-paging.one-indexed-pagesconfiguration option (defaultfalse). Whentrue, page numbers are 1-based on both request and response —?page=1is the first page, response shows"page": 1. See Sorting & Page Numbering for the full contract.PageResponse.withOneIndexedPages()— pure transform invoked by the aspect; also usable directly when constructingPageResponsemanually.- API (Javadoc) reference page linking to javadoc.io with a quick map of the main public types.
Changed¶
- Sorting & Page Numbering guide now documents the new option instead of describing it as a future plan.
- Configuration reference lists
one-indexed-pagesalongside the other tunables.
Notes¶
- Backward compatible — default behavior is 0-based, identical to v0.1.x. Existing consumers do not need to opt in.
[0.1.2] — 2026-05-17¶
Added¶
- This documentation site at easy-paging.devslab.kr — built with MkDocs Material, 14 pages × 2 languages, auto-deployed on every push to
main. - README link to the docs site (both languages).
Changed¶
- POM
<url>now points here (the docs site) instead of the GitHub repository. The "Project" link on Maven Central listings will lead first-time visitors here.
Notes¶
- No functional changes. Consumers do not need to upgrade unless they want the new POM URL in their dependency tooling.
[0.1.1] — 2026-05-15¶
Added¶
- HTTP 400 for invalid sort —
?sort=name;DROP TABLEis now rejected with400 Bad Requestinstead of bubbling up as a generic500. The aspect wrapsIllegalArgumentExceptionfromSortConverterinResponseStatusException(BAD_REQUEST). - JaCoCo coverage —
./gradlew jacocoTestReportemits XML + HTML reports. CI uploads to Codecov on every push tomain. - Coverage and CI badges in both READMEs.
- New integration tests:
AutoPaginateWebMvcIntegrationTest— exercises the aspect through the full Spring MVC stack (happy path, multi-column sort, injection rejection, ThreadLocal cleanup, oversize clamping).PageResponseFactoryIntegrationTest— verifies that a registeredPageResponseFactorybean replaces the default envelope.
Changed¶
- README (both languages) clarifies the 0-based page numbering convention and the fact that
mybatis-spring-boot-starteris not transitive (consumers add it explicitly). - Aspect cleanup is unified: both
SortConverterfailures and mapper exceptions release the PageHelperThreadLocalthrough a singlefinally. - Test fixture
data.sqlresets the identity sequence (TRUNCATE … RESTART IDENTITY) so repeated context starts during a test run see deterministic IDs.
Coverage¶
- Line: 86 % · Branch: 71 % · 43 tests across unit + integration.
[0.1.0] — 2026-05-12¶
Added¶
@AutoPaginateaspect for offset pagination driven by Spring DataPageable, backed by PageHelper. Clamps page size, propagates sort, cleans up the PageHelperThreadLocalinfinally.PageResponse<T>envelope (Spring Data-shaped, Jackson-friendly).SortConverterwith a strict identifier whitelist (rejects SQL injection via thesortquery parameter).@KeysetPaginate+KeysetRequestargument resolver +KeysetPage<T>envelope for cursor-based pagination.Cursor/CursorCodec— Base64-URL JSON tokens with optional HMAC-SHA256 signing, payload size cap, tamper detection.ReactivePagingSupportfor using PageHelper from Reactor code on a blocking-IO scheduler.PageResponseFactorySPI for overriding the default response envelope.- Spring Boot auto-configuration:
EasyPagingAutoConfiguration(core)EasyPagingWebMvcConfiguration(servlet — argument resolver)ReactiveEasyPagingAutoConfiguration(reactor marker)
- Configuration metadata for IDE auto-completion of
easy-paging.*properties. - GitHub Actions workflows for CI and Maven Central release.