Skip to content

Commit 173a62b

Browse files
Thomas Darimontodrotbohm
Thomas Darimont
authored andcommitted
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.
1 parent cbbafce commit 173a62b

File tree

2 files changed

+122
-8
lines changed

2 files changed

+122
-8
lines changed

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

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2012 the original author or authors.
2+
* Copyright 2011-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727
import org.springframework.data.mongodb.core.MongoTemplate;
2828
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
2929
import org.springframework.data.querydsl.EntityPathResolver;
30+
import org.springframework.data.querydsl.QSort;
3031
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
3132
import org.springframework.data.querydsl.SimpleEntityPathResolver;
3233
import org.springframework.data.repository.core.EntityInformation;
@@ -44,6 +45,7 @@
4445
* Special QueryDsl based repository implementation that allows execution {@link Predicate}s in various forms.
4546
*
4647
* @author Oliver Gierke
48+
* @author Thomas Darimont
4749
*/
4850
public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements
4951
QueryDslPredicateExecutor<T> {
@@ -105,7 +107,6 @@ public List<T> findAll(Predicate predicate) {
105107
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, com.mysema.query.types.OrderSpecifier<?>[])
106108
*/
107109
public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
108-
109110
return createQueryFor(predicate).orderBy(orders).list();
110111
}
111112

@@ -115,7 +116,7 @@ public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
115116
*/
116117
@Override
117118
public Iterable<T> findAll(OrderSpecifier<?>... orders) {
118-
return createQueryFor(new Predicate[0]).orderBy(orders).list();
119+
return createQuery().orderBy(orders).list();
119120
}
120121

121122
/*
@@ -130,6 +131,28 @@ public Page<T> findAll(Predicate predicate, Pageable pageable) {
130131
return new PageImpl<T>(applyPagination(query, pageable).list(), pageable, countQuery.count());
131132
}
132133

134+
/*
135+
* (non-Javadoc)
136+
* @see org.springframework.data.mongodb.repository.support.SimpleMongoRepository#findAll(org.springframework.data.domain.Pageable)
137+
*/
138+
@Override
139+
public Page<T> findAll(Pageable pageable) {
140+
141+
MongodbQuery<T> countQuery = createQuery();
142+
MongodbQuery<T> query = createQuery();
143+
144+
return new PageImpl<T>(applyPagination(query, pageable).list(), pageable, countQuery.count());
145+
}
146+
147+
/*
148+
* (non-Javadoc)
149+
* @see org.springframework.data.mongodb.repository.support.SimpleMongoRepository#findAll(org.springframework.data.domain.Sort)
150+
*/
151+
@Override
152+
public List<T> findAll(Sort sort) {
153+
return applySorting(createQuery(), sort).list();
154+
}
155+
133156
/*
134157
* (non-Javadoc)
135158
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#count(com.mysema.query.types.Predicate)
@@ -144,12 +167,17 @@ public long count(Predicate predicate) {
144167
* @param predicate
145168
* @return
146169
*/
147-
private MongodbQuery<T> createQueryFor(Predicate... predicate) {
148-
149-
Class<T> domainType = entityInformation.getJavaType();
170+
private MongodbQuery<T> createQueryFor(Predicate predicate) {
171+
return createQuery().where(predicate);
172+
}
150173

151-
MongodbQuery<T> query = new SpringDataMongodbQuery<T>(mongoOperations, domainType);
152-
return query.where(predicate);
174+
/**
175+
* Creates a {@link MongodbQuery}.
176+
*
177+
* @return
178+
*/
179+
private MongodbQuery<T> createQuery() {
180+
return new SpringDataMongodbQuery<T>(mongoOperations, entityInformation.getJavaType());
153181
}
154182

155183
/**
@@ -182,6 +210,15 @@ private MongodbQuery<T> applySorting(MongodbQuery<T> query, Sort sort) {
182210
return query;
183211
}
184212

213+
// TODO: find better solution than instanceof check
214+
if (sort instanceof QSort) {
215+
216+
List<OrderSpecifier<?>> orderSpecifiers = ((QSort) sort).getOrderSpecifiers();
217+
query.orderBy(orderSpecifiers.toArray(new OrderSpecifier<?>[orderSpecifiers.size()]));
218+
219+
return query;
220+
}
221+
185222
for (Order order : sort) {
186223
query.orderBy(toOrder(order));
187224
}

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.HashSet;
2525
import java.util.List;
2626

27+
import org.hamcrest.Matchers;
2728
import org.junit.Before;
2829
import org.junit.Ignore;
2930
import org.junit.Test;
@@ -47,6 +48,7 @@
4748
import org.springframework.data.mongodb.core.MongoOperations;
4849
import org.springframework.data.mongodb.core.query.BasicQuery;
4950
import org.springframework.data.mongodb.repository.Person.Sex;
51+
import org.springframework.data.querydsl.QSort;
5052
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
5153

5254
/**
@@ -1071,4 +1073,79 @@ public void returnsOrderedResultsForQuerydslOrderSpecifier() {
10711073

10721074
assertThat(result, contains(alicia, boyd, carter, dave, leroi, oliver, stefan));
10731075
}
1076+
1077+
/**
1078+
* @see DATAMONGO-1085
1079+
*/
1080+
@Test
1081+
public void shouldSupportSortingByQueryDslOrderSpecifier() {
1082+
1083+
repository.deleteAll();
1084+
1085+
List<Person> persons = new ArrayList<Person>();
1086+
1087+
for (int i = 0; i < 3; i++) {
1088+
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
1089+
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
1090+
persons.add(person);
1091+
}
1092+
1093+
repository.save(persons);
1094+
1095+
QPerson person = QPerson.person;
1096+
1097+
Iterable<Person> result = repository.findAll(person.firstname.isNotNull(), person.address.street.desc());
1098+
1099+
assertThat(result, is(Matchers.<Person> iterableWithSize(persons.size())));
1100+
assertThat(result.iterator().next().getFirstname(), is(persons.get(2).getFirstname()));
1101+
}
1102+
1103+
/**
1104+
* @see DATAMONGO-1085
1105+
*/
1106+
@Test
1107+
public void shouldSupportSortingWithQSortByQueryDslOrderSpecifier() throws Exception {
1108+
1109+
repository.deleteAll();
1110+
1111+
List<Person> persons = new ArrayList<Person>();
1112+
1113+
for (int i = 0; i < 3; i++) {
1114+
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
1115+
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
1116+
persons.add(person);
1117+
}
1118+
1119+
repository.save(persons);
1120+
1121+
PageRequest pageRequest = new PageRequest(0, 2, new QSort(person.address.street.desc()));
1122+
Iterable<Person> result = repository.findAll(pageRequest);
1123+
1124+
assertThat(result, is(Matchers.<Person> iterableWithSize(2)));
1125+
assertThat(result.iterator().next().getFirstname(), is("Siggi 2"));
1126+
}
1127+
1128+
/**
1129+
* @see DATAMONGO-1085
1130+
*/
1131+
@Test
1132+
public void shouldSupportSortingWithQSort() throws Exception {
1133+
1134+
repository.deleteAll();
1135+
1136+
List<Person> persons = new ArrayList<Person>();
1137+
1138+
for (int i = 0; i < 3; i++) {
1139+
Person person = new Person(String.format("Siggi %s", i), "Bar", 30);
1140+
person.setAddress(new Address(String.format("Street %s", i), "12345", "SinCity"));
1141+
persons.add(person);
1142+
}
1143+
1144+
repository.save(persons);
1145+
1146+
Iterable<Person> result = repository.findAll(new QSort(person.address.street.desc()));
1147+
1148+
assertThat(result, is(Matchers.<Person> iterableWithSize(persons.size())));
1149+
assertThat(result.iterator().next().getFirstname(), is("Siggi 2"));
1150+
}
10741151
}

0 commit comments

Comments
 (0)