Browse Source

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.
pull/257/head
Thomas Darimont 11 years ago committed by Oliver Gierke
parent
commit
173a62b5ce
  1. 53
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java
  2. 77
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

53
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java

@ -1,5 +1,5 @@ @@ -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; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 @@ -144,12 +167,17 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
* @param predicate
* @return
*/
private MongodbQuery<T> createQueryFor(Predicate... predicate) {
Class<T> domainType = entityInformation.getJavaType();
private MongodbQuery<T> createQueryFor(Predicate predicate) {
return createQuery().where(predicate);
}
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 @@ -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));
}

77
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

@ -24,6 +24,7 @@ import java.util.Arrays; @@ -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; @@ -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 { @@ -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"));
}
}

Loading…
Cancel
Save