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


source to share





All Articles