DATAMONGO-1085 - Fixed sorting with Querydsl in QueryDslMongoRepository.
We now translate QSort's OrderSpecifiers into appropriate sort criteria. Previously the OrderSpecifiers were not correctly translated to appropriate property path expressions. We're now overriding support for findAll(Pageable) and findAll(Sort) to QueryDslMongoRepository to apply special QSort handling. Original pull request: #236.
This commit is contained in:
committed by
Oliver Gierke
parent
cbbafce73d
commit
173a62b5ce
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.querydsl.EntityPathResolver;
|
||||
import org.springframework.data.querydsl.QSort;
|
||||
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
||||
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
@@ -44,6 +45,7 @@ import com.mysema.query.types.path.PathBuilder;
|
||||
* Special QueryDsl based repository implementation that allows execution {@link Predicate}s in various forms.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements
|
||||
QueryDslPredicateExecutor<T> {
|
||||
@@ -105,7 +107,6 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, com.mysema.query.types.OrderSpecifier<?>[])
|
||||
*/
|
||||
public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
|
||||
|
||||
return createQueryFor(predicate).orderBy(orders).list();
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
*/
|
||||
@Override
|
||||
public Iterable<T> findAll(OrderSpecifier<?>... orders) {
|
||||
return createQueryFor(new Predicate[0]).orderBy(orders).list();
|
||||
return createQuery().orderBy(orders).list();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -130,6 +131,28 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
return new PageImpl<T>(applyPagination(query, pageable).list(), pageable, countQuery.count());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.support.SimpleMongoRepository#findAll(org.springframework.data.domain.Pageable)
|
||||
*/
|
||||
@Override
|
||||
public Page<T> findAll(Pageable pageable) {
|
||||
|
||||
MongodbQuery<T> countQuery = createQuery();
|
||||
MongodbQuery<T> query = createQuery();
|
||||
|
||||
return new PageImpl<T>(applyPagination(query, pageable).list(), pageable, countQuery.count());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.support.SimpleMongoRepository#findAll(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
public List<T> findAll(Sort sort) {
|
||||
return applySorting(createQuery(), sort).list();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#count(com.mysema.query.types.Predicate)
|
||||
@@ -144,12 +167,17 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
* @param predicate
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> createQueryFor(Predicate... predicate) {
|
||||
private MongodbQuery<T> createQueryFor(Predicate predicate) {
|
||||
return createQuery().where(predicate);
|
||||
}
|
||||
|
||||
Class<T> domainType = entityInformation.getJavaType();
|
||||
|
||||
MongodbQuery<T> query = new SpringDataMongodbQuery<T>(mongoOperations, domainType);
|
||||
return query.where(predicate);
|
||||
/**
|
||||
* Creates a {@link MongodbQuery}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private MongodbQuery<T> createQuery() {
|
||||
return new SpringDataMongodbQuery<T>(mongoOperations, entityInformation.getJavaType());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,6 +210,15 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
|
||||
return query;
|
||||
}
|
||||
|
||||
// TODO: find better solution than instanceof check
|
||||
if (sort instanceof QSort) {
|
||||
|
||||
List<OrderSpecifier<?>> orderSpecifiers = ((QSort) sort).getOrderSpecifiers();
|
||||
query.orderBy(orderSpecifiers.toArray(new OrderSpecifier<?>[orderSpecifiers.size()]));
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
for (Order order : sort) {
|
||||
query.orderBy(toOrder(order));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@@ -47,6 +48,7 @@ import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.repository.Person.Sex;
|
||||
import org.springframework.data.querydsl.QSort;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
@@ -1071,4 +1073,79 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
|
||||
assertThat(result, contains(alicia, boyd, carter, dave, leroi, oliver, stefan));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1085
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportSortingByQueryDslOrderSpecifier() {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
List<Person> persons = new ArrayList<Person>();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
|
||||
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
|
||||
persons.add(person);
|
||||
}
|
||||
|
||||
repository.save(persons);
|
||||
|
||||
QPerson person = QPerson.person;
|
||||
|
||||
Iterable<Person> result = repository.findAll(person.firstname.isNotNull(), person.address.street.desc());
|
||||
|
||||
assertThat(result, is(Matchers.<Person> iterableWithSize(persons.size())));
|
||||
assertThat(result.iterator().next().getFirstname(), is(persons.get(2).getFirstname()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1085
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportSortingWithQSortByQueryDslOrderSpecifier() throws Exception {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
List<Person> persons = new ArrayList<Person>();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
|
||||
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
|
||||
persons.add(person);
|
||||
}
|
||||
|
||||
repository.save(persons);
|
||||
|
||||
PageRequest pageRequest = new PageRequest(0, 2, new QSort(person.address.street.desc()));
|
||||
Iterable<Person> result = repository.findAll(pageRequest);
|
||||
|
||||
assertThat(result, is(Matchers.<Person> iterableWithSize(2)));
|
||||
assertThat(result.iterator().next().getFirstname(), is("Siggi 2"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1085
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportSortingWithQSort() throws Exception {
|
||||
|
||||
repository.deleteAll();
|
||||
|
||||
List<Person> persons = new ArrayList<Person>();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
|
||||
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
|
||||
persons.add(person);
|
||||
}
|
||||
|
||||
repository.save(persons);
|
||||
|
||||
Iterable<Person> result = repository.findAll(new QSort(person.address.street.desc()));
|
||||
|
||||
assertThat(result, is(Matchers.<Person> iterableWithSize(persons.size())));
|
||||
assertThat(result.iterator().next().getFirstname(), is("Siggi 2"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user