From 24cbef9bc5cb03068ca6b29c13af320f9849ddf7 Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Tue, 4 Nov 2014 15:21:21 +0100 Subject: [PATCH] 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. --- .../support/QueryDslMongoRepository.java | 49 ++++++++++-- ...tractPersonRepositoryIntegrationTests.java | 77 +++++++++++++++++++ 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java index 5b41a886a..991369efd 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QueryDslMongoRepository.java @@ -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 extends SimpleMongoRepository implements QueryDslPredicateExecutor { @@ -105,7 +107,6 @@ public class QueryDslMongoRepository extends SimpleM * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, com.mysema.query.types.OrderSpecifier[]) */ public List findAll(Predicate predicate, OrderSpecifier... orders) { - return createQueryFor(predicate).orderBy(orders).list(); } @@ -121,6 +122,28 @@ public class QueryDslMongoRepository extends SimpleM return new PageImpl(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 findAll(Pageable pageable) { + + MongodbQuery countQuery = createQuery(); + MongodbQuery query = createQuery(); + + return new PageImpl(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 findAll(Sort sort) { + return applySorting(createQuery(), sort).list(); + } + /* * (non-Javadoc) * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#count(com.mysema.query.types.Predicate) @@ -136,11 +159,16 @@ public class QueryDslMongoRepository extends SimpleM * @return */ private MongodbQuery createQueryFor(Predicate predicate) { + return createQuery().where(predicate); + } - Class domainType = entityInformation.getJavaType(); - - MongodbQuery query = new SpringDataMongodbQuery(mongoOperations, domainType); - return query.where(predicate); + /** + * Creates a {@link MongodbQuery}. + * + * @return + */ + private MongodbQuery createQuery() { + return new SpringDataMongodbQuery(mongoOperations, entityInformation.getJavaType()); } /** @@ -173,6 +201,15 @@ public class QueryDslMongoRepository extends SimpleM return query; } + // TODO: find better solution than instanceof check + if (sort instanceof QSort) { + + List> orderSpecifiers = ((QSort) sort).getOrderSpecifiers(); + query.orderBy(orderSpecifiers.toArray(new OrderSpecifier[orderSpecifiers.size()])); + + return query; + } + for (Order order : sort) { query.orderBy(toOrder(order)); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java index 6daa8c2f8..3d61ca076 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java @@ -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; /** @@ -1060,4 +1062,79 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(persons, hasSize(1)); assertThat(persons, hasItem(alicia)); } + + /** + * @see DATAMONGO-1085 + */ + @Test + public void shouldSupportSortingByQueryDslOrderSpecifier() { + + repository.deleteAll(); + + List persons = new ArrayList(); + + 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 result = repository.findAll(person.firstname.isNotNull(), person.address.street.desc()); + + assertThat(result, is(Matchers. 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 persons = new ArrayList(); + + 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 result = repository.findAll(pageRequest); + + assertThat(result, is(Matchers. iterableWithSize(2))); + assertThat(result.iterator().next().getFirstname(), is("Siggi 2")); + } + + /** + * @see DATAMONGO-1085 + */ + @Test + public void shouldSupportSortingWithQSort() throws Exception { + + repository.deleteAll(); + + List persons = new ArrayList(); + + 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 result = repository.findAll(new QSort(person.address.street.desc())); + + assertThat(result, is(Matchers. iterableWithSize(persons.size()))); + assertThat(result.iterator().next().getFirstname(), is("Siggi 2")); + } }