Skip to content

Commit ff90891

Browse files
committed
DATAMONGO-1061 - ReadPreference now gets applied on the cursor.
DBCollection instances are cached in the MongoDB driver, which makes them unsuitable for per-operation customization. We previously set the read preference configured on MongoTemplate but that might cause issues if multiple templates with different read preferences are now trying to manipulated the same collection instance. We now rather set the read preference configured on MongoTemplate on the DBCursor as we get a fresh instance for every query execution. Related tickets: https://jira.mongodb.org/browse/JAVA-2293.
1 parent 1a1cd9e commit ff90891

File tree

3 files changed

+25
-27
lines changed

3 files changed

+25
-27
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -805,11 +805,7 @@ protected void ensureNotIterable(Object o) {
805805
*
806806
* @param collection
807807
*/
808-
protected void prepareCollection(DBCollection collection) {
809-
if (this.readPreference != null) {
810-
collection.setReadPreference(readPreference);
811-
}
812-
}
808+
protected void prepareCollection(DBCollection collection) {}
813809

814810
/**
815811
* Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom
@@ -2340,32 +2336,41 @@ public DBCursor prepare(DBCursor cursor) {
23402336
}
23412337

23422338
if (query.getSkip() <= 0 && query.getLimit() <= 0 && query.getSortObject() == null
2343-
&& !StringUtils.hasText(query.getHint()) && !query.getMeta().hasValues()) {
2339+
&& !StringUtils.hasText(query.getHint()) && !query.getMeta().hasValues() && readPreference == null) {
23442340
return cursor;
23452341
}
23462342

23472343
DBCursor cursorToUse = cursor.copy();
23482344

23492345
try {
2346+
23502347
if (query.getSkip() > 0) {
23512348
cursorToUse = cursorToUse.skip(query.getSkip());
23522349
}
2350+
23532351
if (query.getLimit() > 0) {
23542352
cursorToUse = cursorToUse.limit(query.getLimit());
23552353
}
2354+
23562355
if (query.getSortObject() != null) {
23572356
DBObject sortDbo = type != null ? getMappedSortObject(query, type) : query.getSortObject();
23582357
cursorToUse = cursorToUse.sort(sortDbo);
23592358
}
2359+
23602360
if (StringUtils.hasText(query.getHint())) {
23612361
cursorToUse = cursorToUse.hint(query.getHint());
23622362
}
2363+
23632364
if (query.getMeta().hasValues()) {
23642365
for (Entry<String, Object> entry : query.getMeta().values()) {
23652366
cursorToUse = cursorToUse.addSpecial(entry.getKey(), entry.getValue());
23662367
}
23672368
}
23682369

2370+
if (readPreference != null) {
2371+
cursorToUse.setReadPreference(readPreference);
2372+
}
2373+
23692374
} catch (RuntimeException e) {
23702375
throw potentiallyConvertRuntimeException(e, exceptionTranslator);
23712376
}

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@
9292
import com.mongodb.DBRef;
9393
import com.mongodb.Mongo;
9494
import com.mongodb.MongoException;
95-
import com.mongodb.ReadPreference;
9695
import com.mongodb.WriteConcern;
9796
import com.mongodb.WriteResult;
9897

@@ -1115,26 +1114,6 @@ public void testFindOneWithSort() {
11151114
assertThat(p5.getFirstName(), is("Mark"));
11161115
}
11171116

1118-
@Test
1119-
public void testUsingReadPreference() throws Exception {
1120-
this.template.execute("readPref", new CollectionCallback<Object>() {
1121-
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
1122-
assertThat(collection.getOptions(), is(0));
1123-
assertThat(collection.getDB().getOptions(), is(0));
1124-
return null;
1125-
}
1126-
});
1127-
MongoTemplate slaveTemplate = new MongoTemplate(factory);
1128-
slaveTemplate.setReadPreference(ReadPreference.secondary());
1129-
slaveTemplate.execute("readPref", new CollectionCallback<Object>() {
1130-
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
1131-
assertThat(collection.getReadPreference(), is(ReadPreference.secondary()));
1132-
assertThat(collection.getDB().getOptions(), is(0));
1133-
return null;
1134-
}
1135-
});
1136-
}
1137-
11381117
/**
11391118
* @see DATADOC-166
11401119
*/

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.data.mongodb.core.query.Query;
3434

3535
import com.mongodb.DBCursor;
36+
import com.mongodb.ReadPreference;
3637

3738
/**
3839
* Unit tests for {@link QueryCursorPreparer}.
@@ -133,6 +134,19 @@ public void appliesSnapshotCorrectly() {
133134
verify(cursorToUse).addSpecial(eq("$snapshot"), eq(true));
134135
}
135136

137+
/**
138+
* @see DATAMONGO-1061
139+
*/
140+
@Test
141+
public void appliesTemplateReadPreferenceToCursor() {
142+
143+
MongoTemplate template = new MongoTemplate(factory);
144+
template.setReadPreference(ReadPreference.secondary());
145+
template.new QueryCursorPreparer(query(where("foo").is("bar")), getClass()).prepare(cursor);
146+
147+
verify(cursorToUse).setReadPreference(ReadPreference.secondary());
148+
}
149+
136150
private DBCursor pepare(Query query) {
137151

138152
CursorPreparer preparer = new MongoTemplate(factory).new QueryCursorPreparer(query, null);

0 commit comments

Comments
 (0)