Skip to content

Commit 4c7befb

Browse files
christophstroblodrotbohm
authored andcommittedApr 10, 2014
DATAMONGO-888 - Sorting now considers mapping information.
We now pipe the DBObject containing sorting information for queries through the QueryMapper to make sure potential field mappings are applied. Original Pull Request: spring-projects#162.
1 parent b62669e commit 4c7befb

File tree

3 files changed

+119
-16
lines changed

3 files changed

+119
-16
lines changed
 

‎spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
import com.mongodb.WriteResult;
116116
import com.mongodb.util.JSON;
117117
import com.mongodb.util.JSONParseException;
118+
118119
/**
119120
* Primary implementation of {@link MongoOperations}.
120121
*
@@ -354,7 +355,7 @@ protected void logCommandExecutionError(final DBObject command, CommandResult re
354355
}
355356

356357
public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) {
357-
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query));
358+
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query, null));
358359
}
359360

360361
/**
@@ -532,7 +533,7 @@ public <T> List<T> find(final Query query, Class<T> entityClass, String collecti
532533
}
533534

534535
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass,
535-
new QueryCursorPreparer(query));
536+
new QueryCursorPreparer(query, entityClass));
536537
}
537538

538539
public <T> T findById(Object id, Class<T> entityClass) {
@@ -614,8 +615,8 @@ public <T> T findAndModify(Query query, Update update, FindAndModifyOptions opti
614615

615616
public <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass,
616617
String collectionName) {
617-
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
618-
entityClass, update, options);
618+
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(),
619+
getMappedSortObject(query, entityClass), entityClass, update, options);
619620
}
620621

621622
// Find methods that take a Query to express the query and that return a single object that is also removed from the
@@ -626,8 +627,9 @@ public <T> T findAndRemove(Query query, Class<T> entityClass) {
626627
}
627628

628629
public <T> T findAndRemove(Query query, Class<T> entityClass, String collectionName) {
629-
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
630-
entityClass);
630+
631+
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(),
632+
getMappedSortObject(query, entityClass), entityClass);
631633
}
632634

633635
public long count(Query query, Class<?> entityClass) {
@@ -1941,6 +1943,16 @@ private static final MongoConverter getDefaultMongoConverter(MongoDbFactory fact
19411943
return converter;
19421944
}
19431945

1946+
private DBObject getMappedSortObject(Query query, Class<?> type) {
1947+
1948+
if (query == null || query.getSortObject() == null) {
1949+
return null;
1950+
}
1951+
1952+
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
1953+
return queryMapper.getMappedObject(query.getSortObject(), entity);
1954+
}
1955+
19441956
// Callback implementations
19451957

19461958
/**
@@ -2134,9 +2146,12 @@ public WriteConcern resolve(MongoAction action) {
21342146
class QueryCursorPreparer implements CursorPreparer {
21352147

21362148
private final Query query;
2149+
private final Class<?> type;
2150+
2151+
public QueryCursorPreparer(Query query, Class<?> type) {
21372152

2138-
public QueryCursorPreparer(Query query) {
21392153
this.query = query;
2154+
this.type = type;
21402155
}
21412156

21422157
/*
@@ -2164,7 +2179,7 @@ public DBCursor prepare(DBCursor cursor) {
21642179
cursorToUse = cursorToUse.limit(query.getLimit());
21652180
}
21662181
if (query.getSortObject() != null) {
2167-
cursorToUse = cursorToUse.sort(query.getSortObject());
2182+
cursorToUse = cursorToUse.sort(getMappedSortObject(query, type));
21682183
}
21692184
if (StringUtils.hasText(query.getHint())) {
21702185
cursorToUse = cursorToUse.hint(query.getHint());

‎spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,95 @@ public void updateMultiShouldAddValuesCorrectlyWhenUsingAddToSetWithEach() {
25932593
assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3));
25942594
}
25952595

2596+
/**
2597+
* @see DATAMONGO-888
2598+
*/
2599+
@Test
2600+
public void sortOnIdFieldPropertyShouldBeMappedCorrectly() {
2601+
2602+
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
2603+
one.someIdKey = "1";
2604+
one.value = "a";
2605+
2606+
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
2607+
two.someIdKey = "2";
2608+
two.value = "b";
2609+
2610+
template.save(one);
2611+
template.save(two);
2612+
2613+
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "someIdKey"));
2614+
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
2615+
}
2616+
2617+
/**
2618+
* @see DATAMONGO-888
2619+
*/
2620+
@Test
2621+
public void sortOnAnnotatedFieldPropertyShouldBeMappedCorrectly() {
2622+
2623+
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
2624+
one.someIdKey = "1";
2625+
one.value = "a";
2626+
2627+
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
2628+
two.someIdKey = "2";
2629+
two.value = "b";
2630+
2631+
template.save(one);
2632+
template.save(two);
2633+
2634+
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "value"));
2635+
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
2636+
}
2637+
2638+
static class DoucmentWithNamedIdField {
2639+
2640+
@Id String someIdKey;
2641+
2642+
@Field(value = "val")//
2643+
String value;
2644+
2645+
@Override
2646+
public int hashCode() {
2647+
final int prime = 31;
2648+
int result = 1;
2649+
result = prime * result + (someIdKey == null ? 0 : someIdKey.hashCode());
2650+
result = prime * result + (value == null ? 0 : value.hashCode());
2651+
return result;
2652+
}
2653+
2654+
@Override
2655+
public boolean equals(Object obj) {
2656+
if (this == obj) {
2657+
return true;
2658+
}
2659+
if (obj == null) {
2660+
return false;
2661+
}
2662+
if (!(obj instanceof DoucmentWithNamedIdField)) {
2663+
return false;
2664+
}
2665+
DoucmentWithNamedIdField other = (DoucmentWithNamedIdField) obj;
2666+
if (someIdKey == null) {
2667+
if (other.someIdKey != null) {
2668+
return false;
2669+
}
2670+
} else if (!someIdKey.equals(other.someIdKey)) {
2671+
return false;
2672+
}
2673+
if (value == null) {
2674+
if (other.value != null) {
2675+
return false;
2676+
}
2677+
} else if (!value.equals(other.value)) {
2678+
return false;
2679+
}
2680+
return true;
2681+
}
2682+
2683+
}
2684+
25962685
static class DocumentWithDBRefCollection {
25972686

25982687
@Id public String id;

‎spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryCursorPreparerUnitTests.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011 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.
@@ -15,9 +15,9 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18-
import static org.springframework.data.mongodb.core.query.Query.*;
19-
import static org.springframework.data.mongodb.core.query.Criteria.*;
2018
import static org.mockito.Mockito.*;
19+
import static org.springframework.data.mongodb.core.query.Criteria.*;
20+
import static org.springframework.data.mongodb.core.query.Query.*;
2121

2222
import org.junit.Test;
2323
import org.junit.runner.RunWith;
@@ -33,14 +33,13 @@
3333
* Unit tests for {@link QueryCursorPreparer}.
3434
*
3535
* @author Oliver Gierke
36+
* @author Christoph Strobl
3637
*/
3738
@RunWith(MockitoJUnitRunner.class)
3839
public class QueryCursorPreparerUnitTests {
3940

40-
@Mock
41-
MongoDbFactory factory;
42-
@Mock
43-
DBCursor cursor;
41+
@Mock MongoDbFactory factory;
42+
@Mock DBCursor cursor;
4443

4544
/**
4645
* @see DATAMONGO-185
@@ -50,7 +49,7 @@ public void appliesHintsCorrectly() {
5049

5150
Query query = query(where("foo").is("bar")).withHint("hint");
5251

53-
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
52+
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query, null);
5453
preparer.prepare(cursor);
5554

5655
verify(cursor).hint("hint");

0 commit comments

Comments
 (0)
Please sign in to comment.