Skip to content

Conversation

chrshnv
Copy link

@chrshnv chrshnv commented Oct 6, 2025

This PR introduces an implementation of Window Scrolling API for Spring Data JDBC, providing efficient, index-friendly pagination over ordered datasets.
Unlike traditional offset pagination, the new API uses keyset (window) navigation, which enables constant-time performance even on large tables.

Example query:

WHERE ("DUMMY_ENTITY"."ID_PROP" >= :id_prop AND ("DUMMY_ENTITY"."ID_PROP" > :id_prop1 OR ("DUMMY_ENTITY"."POINT_IN_TIME" > :point_in_time))) ORDER BY "DUMMY_ENTITY"."ID_PROP" ASC, "DUMMY_ENTITY"."POINT_IN_TIME" ASC LIMIT 2

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 6, 2025
@chrshnv chrshnv force-pushed the main branch 2 times, most recently from 21ff326 to b717a00 Compare October 6, 2025 15:46
@chrshnv chrshnv changed the title FEATURE: Window Scrolling API (Offset/Keyset pagination) FEATURE: Window Scrolling API (Offset/Keyset pagination) [Spring Data JDBC] Oct 6, 2025
@chrshnv chrshnv force-pushed the main branch 3 times, most recently from 957a9e4 to 66c9da0 Compare October 7, 2025 03:59
@chrshnv
Copy link
Author

chrshnv commented Oct 7, 2025

i guess done. awaiting your reviews!

@chrshnv
Copy link
Author

chrshnv commented Oct 8, 2025

I have a question about the KeysetScrollPosition specification. Should users use property names from POJO or column names from the database?

@chrshnv chrshnv force-pushed the main branch 2 times, most recently from 3b9807e to 9ce9c71 Compare October 8, 2025 18:08
Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: StatementFactory new mode for scroll api

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: basic keyset pagination support (without directions)

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: test with two keys

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: sorting for keys not in query

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: limit support

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: more optimal pg query

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: remove second compare for one-key query

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: me in headers!

Signed-off-by: Artemiy Degtyarev <chereshnyabtw@icloud.com>
Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

code: move to 'ReflectionUtils'

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

add: unit-test for two key query creation

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: fix query generation for three or more keys

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

documentation

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: query test fix

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: invalid next scroll position building due to difference in property and column name

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: remove unexpected sort creation when column already in sort

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: use RelationalPersistentProperty.getName()
instead of RelationalPersistentProperty.getColumnName().getReference()

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: use RelationalPersistentProperty.getName()
instead of RelationalPersistentProperty.getColumnName().getReference()

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

test: use property name instead of database column

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

fix: getColumnName.getReference -> getName

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

code: more beautiful query building

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

code: fix formatting

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

Fix: offset scrolling - calculate query offset by page size

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

Test: add tests for window keyset position after first page

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>
chrshnv added a commit to chrshnv/spring-data-relational that referenced this pull request Oct 9, 2025
Reformat keys extraction code.

See spring-projects#2149

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>
chrshnv added a commit to chrshnv/spring-data-relational that referenced this pull request Oct 9, 2025
Reformat 'applyScrollOrderBy'.

See spring-projects#2149

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>
Reformat keys extraction code.

See spring-projects#2149

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>

Polishing.

Reformat 'applyScrollOrderBy'.

See spring-projects#2149

Signed-off-by: Artemiy Chereshnevvv <chereshnevvv4real@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants