Skip to content

Supports scrolling base on keyset without id#3013

Open
quaff wants to merge 1 commit into
spring-projects:mainfrom
quaff:patch-16
Open

Supports scrolling base on keyset without id#3013
quaff wants to merge 1 commit into
spring-projects:mainfrom
quaff:patch-16

Conversation

@quaff

@quaff quaff commented Jun 12, 2023

Copy link
Copy Markdown
Contributor

id shouldn't be added to sort if provided sort contains unique property.
See GH-2996

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 12, 2023
@mp911de mp911de added the status: on-hold We cannot start working on this issue yet label Jun 12, 2023
@mp911de

mp911de commented Jun 12, 2023

Copy link
Copy Markdown
Member

Removing the primary key isn't going to work, as Keyset scrolling must enforce uniqueness. Just accepting Sort isn't sufficient. What we could do is verify whether a unique property is a part of Sort. If not, we fall back to the primary key.

@quaff

quaff commented Jun 12, 2023

Copy link
Copy Markdown
Contributor Author

Removing the primary key isn't going to work, as Keyset scrolling must enforce uniqueness. Just accepting Sort isn't sufficient. What we could do is verify whether a unique property is a part of Sort. If not, we fall back to the primary key.

IMO, we should add a section in document to elaborate advantage and limitation, guide developers to make best decision, avoid making code more complex.

@mp911de

mp911de commented Jun 12, 2023

Copy link
Copy Markdown
Member

I agree that we should improve the documentation in Commons to explain the relationship of Sort to the query and how we amend the Sort object.

@quaff

quaff commented Jun 12, 2023

Copy link
Copy Markdown
Contributor Author

I mean it is the responsibility of developer to make sure keys combination unique if the document emphasize that.

@quaff quaff marked this pull request as draft June 13, 2023 01:34
@quaff quaff marked this pull request as ready for review June 13, 2023 05:08
@quaff

quaff commented Jun 13, 2023

Copy link
Copy Markdown
Contributor Author

Test improved to cover such cases:

  1. unsorted (implicit sorted by id asc)
  2. explicit sorted by id asc and desc
  3. explicit sorted by seqNo asc and desc
  4. explicit sorted by (id, seqNo) asc and desc

all cases are tested against FORWARD and BACKWARD

@mp911de

mp911de commented Jun 13, 2023

Copy link
Copy Markdown
Member

Please, let's keep pull requests focused instead of mixing concerns within a single pull request.

@quaff

quaff commented Jun 13, 2023

Copy link
Copy Markdown
Contributor Author

Please, let's keep pull requests focused instead of mixing concerns within a single pull request.

Sorry to disturb you, those changes are related and necessary to make the test pass.

@mp911de

mp911de commented Jun 13, 2023

Copy link
Copy Markdown
Member

We don't work towards making tests pass that combine various aspects but rather include coordinated changes. I applied the directional retention via #2999 already. Including unique sort arguments and checking for these requires a bit more changes than we have in this PR.

Towards the sort requirements, we want the calling code to specify sort properties without the requirement to include always properties to make rows unique. Making rows unique is primarily a concern of our keyset scrolling code. If calling code wants to specify sort properties to make the result unique, then we can do so in the course of this pull request.

@mp911de mp911de added type: enhancement A general enhancement and removed status: on-hold We cannot start working on this issue yet status: waiting-for-triage An issue we've not yet triaged labels Jun 13, 2023
@quaff quaff force-pushed the patch-16 branch 3 times, most recently from 071f270 to 1324b29 Compare June 16, 2023 01:56
@quaff

quaff commented Jun 16, 2023

Copy link
Copy Markdown
Contributor Author

KeysetScrollIntegrationTests is extracted to #3030 after #2999 resolved.

@quaff

quaff commented Jun 18, 2023

Copy link
Copy Markdown
Contributor Author

A viable proposal is adding a boolean property (eg. keysetQualified) to Sort, let developer hint that based on unique columns.

@quaff

quaff commented Jul 3, 2023

Copy link
Copy Markdown
Contributor Author

We could introduce a global property indicate that sort is unique ensured by developer.

@mp911de mp911de self-assigned this Jul 19, 2023
@quaff quaff marked this pull request as draft October 24, 2023 03:48
@quaff quaff marked this pull request as ready for review October 24, 2023 05:01
@quaff

quaff commented Oct 24, 2023

Copy link
Copy Markdown
Contributor Author

Commit updated, I introduce method JpaEntityInformation.isKeysetQualified() and default implementation is check whether unique property present, then skip include id in keyset, please take a look @mp911de

@stupid58fly

Copy link
Copy Markdown

Hi @quaff,

Have you considered nullable unique columns?

In standard SQL, a UNIQUE constraint does not prevent multiple NULL values. If the database contains multiple rows where this column is NULL, relying solely on the unique flag for keyset scrolling without an explicit ID fallback might cause unexpected behavior or result in multiple rows being returned.

It would be great to add a test case to ensure this works fine when multiple NULL values are present in the unique column.

@quaff quaff force-pushed the patch-16 branch 2 times, most recently from fede995 to 9191912 Compare June 8, 2026 01:21
@quaff

quaff commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @quaff,

Have you considered nullable unique columns?

In standard SQL, a UNIQUE constraint does not prevent multiple NULL values. If the database contains multiple rows where this column is NULL, relying solely on the unique flag for keyset scrolling without an explicit ID fallback might cause unexpected behavior or result in multiple rows being returned.

It would be great to add a test case to ensure this works fine when multiple NULL values are present in the unique column.

@stupid58fly Updated as you suggested, thanks.

@stupid58fly

Copy link
Copy Markdown

Thanks for the update! I have a couple of thoughts regarding the logic and future extensibility:

  1. Loop Exit Logic & nullable handling:
    It looks like the current exit condition in line 316 and line 326 doesn't fully account for the nullable attribute. To ensure the logic behaves correctly when nullable is present, I think it should be rewritten like this:
   if (column != null) {
       return column.unique() && !column.nullable();
   }
  1. Extensibility for UniqueConstraint:
    Apart from the unique attribute inside the @Column annotation, JPA also provides the @UniqueConstraint annotation (usually defined at the @Table level). Have you considered architectural space for expanding this feature to support @UniqueConstraint in the future? It might be worth keeping the design flexible enough so we can easily plug in table-level constraint scanning later on.

What do you think?

See spring-projectsGH-2996

Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
@quaff

quaff commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the update! I have a couple of thoughts regarding the logic and future extensibility:

  1. Loop Exit Logic & nullable handling:
    It looks like the current exit condition in line 316 and line 326 doesn't fully account for the nullable attribute. To ensure the logic behaves correctly when nullable is present, I think it should be rewritten like this:
   if (column != null) {
       return column.unique() && !column.nullable();
   }
  1. Extensibility for UniqueConstraint:
    Apart from the unique attribute inside the @Column annotation, JPA also provides the @UniqueConstraint annotation (usually defined at the @Table level). Have you considered architectural space for expanding this feature to support @UniqueConstraint in the future? It might be worth keeping the design flexible enough so we can easily plug in table-level constraint scanning later on.

What do you think?

  1. Updated.
  2. I think we shouldn't overcomplicate things, what if a column is nullable in @Column and unique in @UniqueConstraint or missing from annotation but in DDL? It's likely impossible to cover all cases, covering most common case is enough.

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.

4 participants