How can I know the position of a record in a JPA query?
I have a service that returns paged results implementing more or less a method with this signature:
List<Record> getRecordsPage(long page, int pageSize);
When this is invoked I just create a query and configure like this:
TypedQuery<Record> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);
This pages the result. And this is working as expected, and is quite simple.
The Problem
Another requirement I have is to implement a method that would retrieve the page that contains a specific record. Implementing a method with the following signature:
List<Record> getRecordsPage(Record record, int pageSize);
This method needs to result the right page in which the record is. For instance, for getRecordsPage(RECORD4, 2)
invocation, considering database state:
1. RECORD1
2. RECORD2
3. RECORD3
4. RECORD4
5. RECORD5
The returned page should be 2 containing [RECORD3, RECORD4]
.
The ORDER BY
parameter is always set, and could be more than one field.
Solution Until Now
Until now I have a few solutions that are:
- Not good at all but it solves the problem:
Using the query provided I select just the id without paging and perform just a indexOf
in order to find its position and based on the position I can find out the page the record is and then perform the regular process using getRecordsPage(long page, int pageSize)
already implemented.
- Not so good because is high coupled with database:
As I'm using mySQL, I could perform an sql like : select r from (select rownum r, id from t order by x,y) z where z.id = :id
, what would return the position of the record and I could use it in order to invoke getRecordsPage(long page, int pageSize)
.
Good Solution
Requirements:
- shall support order by multiple fields;
- given a query, it will return the record position or the containing record page offset;
A good solution would:
- be purely JPA;
- be Ok if one additional query is performed in database just to find out the record position;
- be Ok if hibernate is used in some point (as Hibernate is behind JPA in this case).