QueryDsl Sort Dynamically
I would like the spring data to return a smaller dto class instead of my full objects.
With QueryDsl and spring Data JPA, I tried to create a service that asks for EntityPath, but returns me a compatible data transfer object. I would like to build this query dynamically.
<!-- language: java -->
/**
* @param type The dto class you want to query
* @param ep The entitypath for the full class (generated QClass)
* @param pageRequest The spring data jpa domain pagerequest instance
* @param predicate predicate generated by .getValue() on a BooleanExpression
*/
@Override
public Page<? extends DtoMarker> getPagedResultsForDto(Class<? extends DtoMarker> type, EntityPath<?> ep , PageRequest pageRequest, Predicate predicate) throws NoSuchFieldException, SecurityException{
List<Expression<?>> expressions = getExpressions(type, ep);
JPAQuery query = new JPAQuery(em);
query = query.from(ep).where(predicate);
if (pageRequest != null) {
query = query.limit(pageRequest.getPageSize()).offset(pageRequest.getOffset());
}
if (pageRequest.getSort() != null) {
for (Sort.Order o : pageRequest.getSort()) {
query = query.orderBy(toOrderSpecifier(o, ep));
}
}
List<? extends DtoMarker> tuples = query.list(Projections.bean(type, expressions.toArray(new Expression[expressions.size()])));
return new PageImpl<>(tuples, pageRequest, getCountTotalSizeForDto(type, ep, pageRequest, predicate));
}
private List<Expression<?>> getExpressions(Class<? extends DtoMarker> type,
EntityPath<?> ep) {
List<Expression<?>> expressions = new ArrayList<Expression<?>>();
List<Field> fields = new ArrayList<Field>();
for (Field field : type.getDeclaredFields()){
fields.add(field);
}
for (Field field : type.getSuperclass().getDeclaredFields()){
fields.add(field);
}
for (Field field : fields) {
String generictype = field.getType().getSimpleName();
if (generictype.equals("String")){
expressions.add(new StringPath(ep, field.getName()));
}
if (generictype.equals("Boolean")) {
expressions.add(new BooleanPath(ep, field.getName()));
}
if (generictype.equals("Long")) {
expressions.add(new NumberPath<Long>(Long.class, ep, field.getName()));
}
}
return expressions;
}
This works very well, the only problem is how I am implementing the sort. I am converting jpa spring collation to querydsl file with:
<!-- language: java -->
@SuppressWarnings({ "rawtypes", "unchecked" })
private OrderSpecifier<?> toOrderSpecifier(Order order, EntityPath<?> ep) {
ComparablePath<?> sortPropertyExpression = new ComparablePath(Comparable.class, ep, order.getProperty());
com.mysema.query.types.Order orderExpression = order.isAscending() ? com.mysema.query.types.Order.ASC
: com.mysema.query.types.Order.DESC;
return new OrderSpecifier(orderExpression, sortPropertyExpression);
}
But this is because the lines are not sorted by ignorecase (= requirement)!
Maybe this could be a road to a solution ?:
<!-- language: java -->
sortPropertyExpression = order.isIgnoreCase() ? Expressions.stringPath(order.getProperty()).lower() : Expressions.stringPath(order.getProperty());
But it only works for stringPaths and gives exceptions for numberpath, etc.
Any other ideas I could use for dynamic sorting?
+3
Mark
source
to share
No one has answered this question yet
Check out similar questions:
23498
1544
15
ten
6
4
3
2
1
0