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>
@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 20, 2025
@mp911de
Copy link
Member

mp911de commented Oct 20, 2025

Thanks for your pull request. This is interesting but we don't have currently the bandwidth to evolve JDBC support. We will come back to this one next year or so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: enhancement A general enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants