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: #162.
This commit is contained in:
committed by
Oliver Gierke
parent
b62669ec8f
commit
4c7befb910
@@ -115,6 +115,7 @@ import com.mongodb.WriteConcern;
|
||||
import com.mongodb.WriteResult;
|
||||
import com.mongodb.util.JSON;
|
||||
import com.mongodb.util.JSONParseException;
|
||||
|
||||
/**
|
||||
* Primary implementation of {@link MongoOperations}.
|
||||
*
|
||||
@@ -354,7 +355,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) {
|
||||
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query));
|
||||
executeQuery(query, collectionName, dch, new QueryCursorPreparer(query, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,7 +533,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass,
|
||||
new QueryCursorPreparer(query));
|
||||
new QueryCursorPreparer(query, entityClass));
|
||||
}
|
||||
|
||||
public <T> T findById(Object id, Class<T> entityClass) {
|
||||
@@ -614,8 +615,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
public <T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass,
|
||||
String collectionName) {
|
||||
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
|
||||
entityClass, update, options);
|
||||
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(),
|
||||
getMappedSortObject(query, entityClass), entityClass, update, options);
|
||||
}
|
||||
|
||||
// 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 class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
|
||||
public <T> T findAndRemove(Query query, Class<T> entityClass, String collectionName) {
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
|
||||
entityClass);
|
||||
|
||||
return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(),
|
||||
getMappedSortObject(query, entityClass), entityClass);
|
||||
}
|
||||
|
||||
public long count(Query query, Class<?> entityClass) {
|
||||
@@ -1941,6 +1943,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return converter;
|
||||
}
|
||||
|
||||
private DBObject getMappedSortObject(Query query, Class<?> type) {
|
||||
|
||||
if (query == null || query.getSortObject() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
return queryMapper.getMappedObject(query.getSortObject(), entity);
|
||||
}
|
||||
|
||||
// Callback implementations
|
||||
|
||||
/**
|
||||
@@ -2134,9 +2146,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
class QueryCursorPreparer implements CursorPreparer {
|
||||
|
||||
private final Query query;
|
||||
private final Class<?> type;
|
||||
|
||||
public QueryCursorPreparer(Query query, Class<?> type) {
|
||||
|
||||
public QueryCursorPreparer(Query query) {
|
||||
this.query = query;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2164,7 +2179,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
cursorToUse = cursorToUse.limit(query.getLimit());
|
||||
}
|
||||
if (query.getSortObject() != null) {
|
||||
cursorToUse = cursorToUse.sort(query.getSortObject());
|
||||
cursorToUse = cursorToUse.sort(getMappedSortObject(query, type));
|
||||
}
|
||||
if (StringUtils.hasText(query.getHint())) {
|
||||
cursorToUse = cursorToUse.hint(query.getHint());
|
||||
|
||||
@@ -2593,6 +2593,95 @@ public class MongoTemplateTests {
|
||||
assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-888
|
||||
*/
|
||||
@Test
|
||||
public void sortOnIdFieldPropertyShouldBeMappedCorrectly() {
|
||||
|
||||
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
|
||||
one.someIdKey = "1";
|
||||
one.value = "a";
|
||||
|
||||
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
|
||||
two.someIdKey = "2";
|
||||
two.value = "b";
|
||||
|
||||
template.save(one);
|
||||
template.save(two);
|
||||
|
||||
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "someIdKey"));
|
||||
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-888
|
||||
*/
|
||||
@Test
|
||||
public void sortOnAnnotatedFieldPropertyShouldBeMappedCorrectly() {
|
||||
|
||||
DoucmentWithNamedIdField one = new DoucmentWithNamedIdField();
|
||||
one.someIdKey = "1";
|
||||
one.value = "a";
|
||||
|
||||
DoucmentWithNamedIdField two = new DoucmentWithNamedIdField();
|
||||
two.someIdKey = "2";
|
||||
two.value = "b";
|
||||
|
||||
template.save(one);
|
||||
template.save(two);
|
||||
|
||||
Query query = query(where("_id").in("1", "2")).with(new Sort(Direction.DESC, "value"));
|
||||
assertThat(template.find(query, DoucmentWithNamedIdField.class), contains(two, one));
|
||||
}
|
||||
|
||||
static class DoucmentWithNamedIdField {
|
||||
|
||||
@Id String someIdKey;
|
||||
|
||||
@Field(value = "val")//
|
||||
String value;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (someIdKey == null ? 0 : someIdKey.hashCode());
|
||||
result = prime * result + (value == null ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof DoucmentWithNamedIdField)) {
|
||||
return false;
|
||||
}
|
||||
DoucmentWithNamedIdField other = (DoucmentWithNamedIdField) obj;
|
||||
if (someIdKey == null) {
|
||||
if (other.someIdKey != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!someIdKey.equals(other.someIdKey)) {
|
||||
return false;
|
||||
}
|
||||
if (value == null) {
|
||||
if (other.value != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class DocumentWithDBRefCollection {
|
||||
|
||||
@Id public String id;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 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.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -33,14 +33,13 @@ import com.mongodb.DBCursor;
|
||||
* Unit tests for {@link QueryCursorPreparer}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QueryCursorPreparerUnitTests {
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@Mock
|
||||
DBCursor cursor;
|
||||
@Mock MongoDbFactory factory;
|
||||
@Mock DBCursor cursor;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-185
|
||||
@@ -50,7 +49,7 @@ public class QueryCursorPreparerUnitTests {
|
||||
|
||||
Query query = query(where("foo").is("bar")).withHint("hint");
|
||||
|
||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query);
|
||||
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query, null);
|
||||
preparer.prepare(cursor);
|
||||
|
||||
verify(cursor).hint("hint");
|
||||
|
||||
Reference in New Issue
Block a user