beginner_
beginner_

Reputation: 7622

How can I convert a spring data Sort to a querydsl OrderSpecifier?

This is basically the opposite of this: How to do a paged QueryDSL query with Spring JPA?

This is for a custom query for which i can't use any of the findAll() methods.

EDIT:

Posted the wrong link. Now corrected.

Upvotes: 19

Views: 31662

Answers (5)

sha-mik
sha-mik

Reputation: 191

Alternatively, if you want to directly apply the sort into your base query without having to convert to OrderSpecifier<?>, you can leverage org.springframework.data.jpa.repository.support.Querydsl.

JPQLQuery<?> query = new JPAQuery<>(entityManager);
//prepare your base query
query.select(<YourQEntity>).from(<YourQEntity>).where(<whereClause>);

Querydsl querydsl = new Querydsl(entityManager, (new PathBuilderFactory()).create(<YourEntityClass>.class));

//apply org.springframework.data.domain.Sort
querydsl.applySorting(pageable.getSort(), query);

Upvotes: 0

Frank
Frank

Reputation: 708

You can do somethings like this: But make sure to trim the o.getProperty() so you only pass the property and not "alias."+property

if (pageable != null) {
    query.offset(pageable.getOffset());
    query.limit(pageable.getPageSize());
    for (Sort.Order o : pageable.getSort()) {
        PathBuilder<Object> orderByExpression = new PathBuilder<Object>(Object.class, "object");

        query.orderBy(new OrderSpecifier(o.isAscending() ? com.mysema.query.types.Order.ASC
                : com.mysema.query.types.Order.DESC, orderByExpression.get(o.getProperty())));
    }
}

Upvotes: 22

Junyeong Yeo
Junyeong Yeo

Reputation: 151

private OrderSpecifier<?>[] getSortedColumn(Sort sorts){   
    return sorts.toList().stream().map(x ->{
        Order order = x.getDirection().name() == "ASC"? Order.ASC : Order.DESC;
        SimplePath<Object> filedPath = Expressions.path(Object.class, Qobject, x.getProperty());
        return new OrderSpecifier(order, filedPath);
    }).toArray(OrderSpecifier[]::new);
}

then you can use like this:

  .where(...), 
  .orderBy(getSortedColumn(pageable.getSort()))

Upvotes: 6

Dario
Dario

Reputation: 53

org.springframework.data.domain.Sort.Order and com.querydsl.core.types.Order and are so similar, yet there is no straightforward conversion between the two. This is somewhat improved version of frozenfury answer:

PathBuilder<Entity> entityPath = new PathBuilder<>(Entity.class, "entity");
for (Order order : pageable.getSort()) {
    PathBuilder<Object> path = entityPath.get(order.getProperty());
    query.orderBy(new OrderSpecifier(com.querydsl.core.types.Order.valueOf(order.getDirection().name()), path));
}

Upvotes: 4

existenz31
existenz31

Reputation: 382

I don't know if it is still relevant but there is an implementation in the spring data jpa for doing the conversion between a data.domain.Sort (Spring JPA) Object to an OrderSpecifier (QueryDSL).

GIT Source of Querydsl Support in Spring JPA

It is really ugly implementation but you could still reuse it for your own purpose as the method is private:

public JPQLQuery applySorting(Sort sort, JPQLQuery query)

But if you use Spring data JPA, in your custom Repository implementation, you just need to do:

public Page<MyObject> findAll(Predicate predicate, Pageable pageable) {

    QMyObject myObject = QMyObject.myObject;
    JPQLQuery jPQLQuery = from(myObject)
            .join(myObject.user)
            .where(predicate);
    jPQLQuery = getQuerydsl().applyPagination(pageable, jPQLQuery);
    List<MyObject> myObjectList = jPQLQuery.list(myObject);
    long count =  jPQLQuery.count();
    Page<MyObject> myObjectPage = new PageImpl<MyObject>(myObjectList, pageable, count);
    return myObjectPage;  
}

Hope it could help!

Upvotes: 9

Related Questions