How to do a paged QueryDSL query with Spring JPA?
-
12-12-2019 - |
Question
QueryDSL defines an OrderSpecifier
interface and an instance for that can be easily obtained for any field by calling asc()
or desc()
. The QueryDslPredicateExecutor
interface of Spring Data JPA even has a findAll()
method which takes OrderSpecifier
s as parameters.
org.springframework.data.domain.PageRequest
however doesn't know anything about QueryDSL and it has its own way for defining query sort order, namely org.springframework.data.domain.Sort
. It can contain a number of org.springframework.data.domain.Sort.Order
s which are a lot like OrderSpecifier
s, except that they are not type safe etc.
So, if I want to make paged query which uses sorting, is there really no way of using QueryDSL for defining that?
Solution
It should work like this if you can't find another way
private Sort sortBy(Path<?> path) {
return new Sort(Sort.Direction.ASC, path.getMetadata().getExpression().toString());
}
OTHER TIPS
I know it's been a while and I'm not sure this was available at the time of the OP but there is now a QPageRequest object introduced which allows for sorting via QueryDSL to be added to spring data jpa Query DSL...
Here is a much simpler way to construct a Sort
object using QueryDSL:
new QSort(user.manager.firstname.asc())
Then you can use it in a PageRequest
like so:
new PageRequest(0, 10, new QSort(user.manager.firstname.asc()))
The getExpression()
method has been removed, and I had expressions akin to QPost.post.period.periCode
which needed a traversal, and without the complete name of expression I couldn't do anything about it, so now I made a method that gathers period.periCode
and works perfectly on QPost.post
.
private String resolveOrderPath(Path<?> path) {
StringBuilder stringBuffer = new StringBuilder(path.getMetadata().getName());
path = path.getMetadata().getParent();
while(!path.getMetadata().isRoot()) {
stringBuffer.insert(0, path.getMetadata().getName() + ".");
path = path.getMetadata().getParent();
}
return stringBuffer.toString();
}
Path<?> path = QPost.post.period.periCode;
String propertyPath = resolveOrderPath(path);
Sort sort = new Sort("asc".equals(sSortDir0) ? Sort.Direction.ASC : Sort.Direction.DESC, propertyPath);