-
Notifications
You must be signed in to change notification settings - Fork 33
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
PageRequest without Sort is allowed #1010
Comments
Sure, you're supposed to either write something like: @Find
@OrderBy(_Book.PUBLICATION_YEAR)
List<Book> booksByPublicationYear(
@By(_Book.PUBLICATION_YEAR) Year year,
PageRequest pageable); or, as you say, include a parameter of type A Note that the sec does already require that a repository method returning |
I was surprised to see we allow data/api/src/main/java/jakarta/data/page/PageRequest.java Lines 31 to 34 in 040f0c6
I suppose it makes sense for someone who doesn't want to deal with the In any case, I see the following requirement on the user to ensure an order: data/api/src/main/java/module-info.java Lines 796 to 798 in 040f0c6
The intent of this was likely to state that it's okay to order on the Id, but alternatively it's also okay not to if you have some other way, like maybe for bank accounts a combination of routingNumber, accountNumber that together define an order. I suppose this could also allow for a default ordering that is provided by a database or even a Jakarta Data provider chosen default. If others feel it is important, I'd also be open to allowing no order and standardizing a default to use when no order is specified, such as by Id ascending, which I suppose would benefit users who don't care about an order so they wouldn't need to bother supplying any. I should also point out, I don't think some of the arguments made in this issue are correct. It says,
That's actually a |
Thank you for your response, @gavinking. I'm on your team, and I'm not exactly sure that the spec should forbid it entirely. However, the core of the problem, I think, is that the The problem is that the so-called What I think is the problem is that I hope my concern is clear for you, Gavin. Let me know what you think about it |
So if the question is: should a
Well, no, that's not necessarily true. If you have a repository method with a JDQL But on the other hand almost no
And so to do pagination you also need carry those things around, not just the dynamic ordering criteria (if any). I don't see how it would be consistent at all to say that |
I disagree @gavinking. The consistency tha I'm talkina about is that the spec currently provide a way to fetch data by using solely |
That's true, but the filtering is every bit as important as the ordering, and even more the entity type that you want to retrieve pages of (this is provided by the repository method return type, not the PageRequest).
That's a very strong statement and I'm trying to figure out what it really means. I think you are saying that a user can forget to include ordering with |
Highly appretiate your response, @njr-11
Of course it is. I'm not saying it is not important. I just do not understand why the question was including this in the
Well, yeah, I agree with you here.
That is not necesserely true. What you're saying is true only in case of prefefined methods in repositories, or when we return the I agree with you, that signature that accepts
While I agree with you, I'm not saying that Spring Data solves this problem in ideal way. What I said is that in Spring Data the I just want to clarify, I do not think it is a great solution from Spring Data. I'm just saying that Sorting is in the object. |
That is true; it does not make the API safe enough for Java developers. Having a default way to solve it won't be bad, such as Spring does with |
But Nathan's point is that you can do that in Spring Data too. Just because a And the issue is that we simply can't prevent the creation of a |
I perfectly got you @gavinking, I'm not saying Spring Data's solution is perfect, I stated it explicitly. What I think we can and should do - at least supply a warning, that the described setup with |
So I think the semantically strong thing here that @mipo256 is reaching for, and which I think that the Spring Data people were grasping for but missed, is the idea of some sort of true multi-page result set or cursor-type object. This is something I privately toyed with when we were working on Data 1.0, but ultimately there were questions I just couldn't answer about it. The programming model would be approximately this: Pages<Book> pages = library.booksByPublicationYear(Year.now(), _Book.title.asc(), PageRequest.ofSize(50));
List<Book> firstPage = pages.page(0);
...
List<Book> secondPage = pages.page(1);
... Where a My issue with this construct, and the reason I never talked about it out loud until now is: how is the application program supposed to store an instance of I suppose that @mipo256 has some way to store a Spring |
@gavinking I'll respond shortly, a bit busy. |
Well, maybe you can put it this way. In general, the question of who would remember the position of the cursor between requests (which is what you're asking, if I understood you correctly) is quite broad, and it highly depends on the context, see examples below. So, for instance, if we have the following method
Assume we have a front-end client. It can provide the page number as the users scrolls down, and page size in order for us to create the It is just a single example. Another example is to use a batch processing within an app. For instance, I need to process all the books via some criteria and do something with them. The dataset is quite large, I do not want to load everything onto memory at once, so I load it with chunks - via @gavinking Maybe I did not understand you correctly, I'm sorry. P.S: Yes, I know the |
So let's quickly dispatch with the batch processing scenario, because it's easy: Unfortunately, As far as I understand it, a typical web endpoint is always going to receive something like:
and then the Java code which handles this endpoint is going to have to unpack the HTTP parameters into Java objects and forward them to a repository, using something like: var books =
library.booksByPublicationYear(Year.of(year),
Sort.asc(sort),
PageRequest.ofPage(page).size(results)); where the repository method is declared as: @Find
List<Book> booksByPublicationYear(Year publicationYear,
Sort<Book> sorting,
PageRequest page); Now, considering this scenario, did it help when we had the
Similarly, would my So the reason for keeping all these parameters separate is that you actually gain type safety. |
Thank you for your response, Gavnin @gavinking
Yes, but that is only because the suer can forget about
The API allows using If we're using this API, then of course forgetting the
Another thing - I do not necessarily think that |
I've already explained why this is simply a non-starter. The common case here is that the repository method itself specifies a well-defined ordering. Dynamic ordering is the less common case. The most basic usage of the API is of this form: @Query("where lower(title) like :title order by title")
List<Book> booksTitled(String title, PageRequest page); var books = library.booksTitled("%hibernate%", PageRequest.ofSize(25)); There is nothing wrong with the code above. We absolutely do not want to force the caller to have to re-specify the ordering in this case! So what you're suggesting simply doesn't work. You need to let go of it.
But then we would arrive at a worse loss of type safety than the one you're worried about! Because then you could pass
So, if we really did decide that you're right, and that pagination with no order is something catastrophic that we need to prevent at compile time (as indicated, I'm really not convinced of this) then the way we would have to do it would be by saying that every repository method with a parameter of type
We could in principle do that, but I'm just not sure we need to. I mean, in our implementation of Jakarta Data we can easily output a compiler warning in this case, and that doesn't require any change to the spec. |
Hey @gavinking! Sorry for delay.
I agree, I see what you're talking about, I overlooked it.
I think we're talking about a bit differnt things here. I'm not talkinag about the dynamic or static sorting configuration. In the meantime, we have discussed this issue internally with @aleksey-stukalov (I think Gavin is familiar with this person), and I encourage him to participate in this conversation on GitHub. Let me explain what we narrowed: The current approach like that:
may be fine, depending on the Jakarta Data vendor. Also, it does not seem to be clear that the Jakarta Data specifiction itself needs to do something about it, since it is reasonable that someone does not need sorting in request at all and just what a subset of data. What we agreed is the case, is that the various implementations should decide, wether they should, for instance, emit a warning, or not. Becuase in Hibernate as Jakarta Data implementation, when it works with PostgreSQL for instance, the query like that:
would yield unpredictable results, that's just what happens. But the fact is that this is not necessary true for other implementations of Jakarta Data or other RDBMs vendos. So, finally, it seems appropriate that:
What are your thoughts on this, @gavinking ? |
Well I actually already did that here: hibernate/hibernate-orm@00de402 But it doesn't really work as well as I would have liked because IntelliJ kinda hides compiler warnings from the user. So those warnings are only visible if you go hunting for them. |
Note however, that this is something that could be implemented directly in IntelliJ's Jakarta Data support. |
@gavinking, could you please elaborate a bit more on that? It definitely would be great to show such warnings to the users in the form of inspection and/or the warning itself in the build output. I don't quite understand how we can hide it out in the current implementation. I'll ask the team to investigate that, but it would be great if you could add a bit more details regarding the problem |
As for the initial question, it is my perception, not more, but I would rather say that the spec meets my personal understanding. I see pagination as a "form" of output, which can be implemented in multiple ways, while ordering is still a part of the data request part. In other words, "order by" is a part of the query declaration, and pagination is about presentation logic that is not necessarily a part of the underlying query. |
Well the thing is that in the case of a compiler error, IntelliJ automatically opens up the Build view, and shows me the error. But for a warning, if the Build view isn't already open and focussed, I won't see the warning. This is usually a reasonable behavior, but it means there's no good way for an annotation processor to provide warnings to the developer. |
Ah, yes, I see. Let's discuss this with the UX team anyway. Will see what they offer. |
Seems this is the consensus of everyone here, so I'm going to close the issue. Going forward, this is a problem that can be dealt with by implementations and by tools. |
Currently, the spec defines
PageRequest
as an object, that encapsulates the pagination info. And we have the separateSort
object that presents the sorting capabilities.The spec allows to have queries like this:
When using Hibernate as an implementation, for instance, this would translate into this SQL statement:
The problem is that the pagination itself often does not make much sense without sorting. The query above would yield unpredictable results, according to ANSI SQL. Even assuming other implementation of Jakarta Data that do not work with RDBMS, they work over storages that often do not have strong guarantees of order of values/documents/records in the result stream if the client did not ask it explicitely.
That is why in Spring Framework, for instance, the
PageRequest
would always have Sorting component in it.My problem is that currently the spec allows for methods with
PageReqeust
, but withoutSort
parameter. That invites problems into peoplesThe text was updated successfully, but these errors were encountered: