-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: PageRequest doesn't know whether it's a Builder #672
Comments
I saw this this weekend. Doing a ballparking implementation, since we have two paginations, I would create specializations: Doing a ball park implementation: classDiagram
PageRequest <|-- OffSetPagination
PageRequest <|-- CursoredPagination
PageRequest: long size()
PageRequest: CursoredPagination beforeKey()
PageRequest: CursoredPagination afterCursor()
OffSetPagination: page()
CursoredPagination: next()
CursoredPagination: previous()
CursoredPagination: cursor()
|
@otaviojava Yes, that's an option indeed. Though I'm also looking for options which have a smaller blast radius. |
We should get rid of the |
Ah. See I did not understand that. |
So the question is: who is the client of those operations of |
The purpose of page.nextPageRequest and page.previousPageRequest is for application usage. They are used in many places in the TCK, mirroring actual application usage patterns. |
I meant to write |
Oh, you question makes a lot more sense now. As far as I'm aware, there is no purpose whatsoever for the |
Nono, I know you want to get rid of those ones, and that's fine. My question is: who is the called of all the other methods like Because if the answer is: usually a provider, or a library, then I think we need to move all those operations to an SPI. |
or it can do
Similarly, Here is one example,
Here is an example of requesting a previous page with intentional overlap of 2 results:
|
OK, well today it's broken for that usage. If you call So we need to either fix it or remove it. |
Both of your examples show usage of |
…f PageRequest Signed-off-by: Nathan Rauh <[email protected]>
That's good.
Technically you could put builder in the name, but that doesn't look very nice in application code and it is better to keep its current name. The entire purpose of |
Then it shouldn't be the object that is passed to a repository method, and returned by
This would be fine if the copy-on-write methods always returned a |
I don't see what is wrong with that. It is fine to supply a builder instance to a method and to receive a builder instance from a method. They are immutable instances so it is impossible to modify them and cause side effects. It does seem a little awkward that the builder never builds an instance of and the configuration is instead read directly from it. If we wanted, we could have it build something and access the configuration from that. I'd rather not clutter the application's API usage with that, but if we want to isolate that to providers, I'd be fine with it.
Is the combination of page and cursor the only area where you see there being inconsistent state? If so, we should look into solving that specific issue rather than redesigning everything. We could easily define it to raise an error for specific invalid combinations. That said, I don't see what is wrong with |
I believe so, yes. |
OK, so look, I'm an application programmer. I get back a Now let's say the user clicked on the link to go to page It seems like totally legit to call: But with the current implementation that just sent you back to the exact same page you were just on. Because your |
That's an excellent example - thanks for identifying it! Given that the scenario is a very useful one for offset pagination, I think a good approach to take here is to specify that |
Meh. That's not typesafe. It's easy to come up with a typesafe solution: simply move that operation to an SPI. |
Really, |
Sure, I'm fine with that. I'll switch over to removing it entirely. |
So then implementations would use: PageRequest.ofPage(pagination.page()+1).size(pagination.size()).afterCursor(_cursors.get(_cursors.size()-1)) I dunno, would it not be better to just remove the methods like PageRequest.afterCursor(pagination.size(), pagination.page()+1, _cursors.get(_cursors.size()-1))) or even just, hear me out: new Pagination(pagination.size(), pagination.page()+1, _cursors.get(_cursors.size()-1))) after moving It's just simpler and less confusing. |
Signed-off-by: Nathan Rauh <[email protected]>
…f PageRequest Signed-off-by: Nathan Rauh <[email protected]>
Signed-off-by: Nathan Rauh <[email protected]>
That seems like it would be reasonable. I added a commit to the pull with this (and also rebased on to latest). |
Specification Version
1.0.0-M3
Bug report
PageRequest
has multiple operations capable of producing an object in an inconsistent state. The most dangerous of these ispage(long)
, which looks harmless enough but actually results in something completely broken if you call it an aPageRequest
with aCursor
. And there's no warning of this in the Javadoc, even. On the other hand, it also has operations likenext()
which are written to be called by the application.It is in no way obvious to the user that these operations
page(long)
andnext()
are so different in nature. So much so that even I have tripped up twice over the difference and I am far from a casual user of this API.We need to remove these dangerous operations to a
Builder
-type object, or do what I suggested a while ago, and expose the constructor ofPagination
to Jakarta Data implementations and simply remove the "dangerous" methods. (This is the simplest solution.)Additional information
No response
The text was updated successfully, but these errors were encountered: