I created this two entites to demonstrate my problem:
OwnerEntity.java:
@Entity
public class OwnerEntity {
@Id
@GeneratedValue(strategy = Ge
String orderSort=page.getSort().toString();
Pageable page1 =
PageRequest.of(page.getPageNumber(),page.getPageSize(),
JpaSort.unsafe(Sort.Direction.valueOf
(orderSort.substring(page.getSort().toString().indexOf(':')+2,
orderSort.length())),
orderSort.substring(0,page.getSort().toString().indexOf(')')+1)));
In the context of a Pageable controller's entry point, I adapted the answer from Dario Seidl to the following:
public static Pageable parenthesisEncapsulation(final Pageable pageable) {
Sort sort = Sort.by(Collections.emptyList());
for (final Sort.Order order : pageable.getSort()) {
if (order.getProperty().matches("^\\(.*\\)$")) {
sort = sort.and(JpaSort.unsafe(order.getDirection(), order.getProperty()));
} else {
sort = sort.and(Sort.by(order.getDirection(), order.getProperty()));
}
}
return PageRequest
.of(pageable.getPageNumber(), pageable.getPageSize(), sort);
}
I can give my controller sort instruction like this:
/myroute?sort=(unsafesortalias),desc&sort=safesortfield,asc
This is a bug in Spring Data: the aliases are not detected correctly. It has also been reported here.
In QueryUtils in the applySorting
method, only (outer) join aliases and function aliases with exactly one pair of parenthesis are detected. A simple alias for a property doesn't work currently.
One workaround for this is to use JpaSort.unsafe
with the aliases in parenthesis when building the PageRequest
, e.g.
PageRequest.of(0, 3, JpaSort.unsafe(Sort.Direction.ASC, "(name)"))
This is unsafe as the name implies, when sorting dynamically based on user input, so it should only be used for hard-coded sorting.