Skip to content

Commit 270456e

Browse files
committed
Polishing.
Extract query that yields no hits into constant. Guard Map-typed reference properties against empty $or. See #3805 Original pull request: #3807.
1 parent 4e960a9 commit 270456e

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

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

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
*/
6363
public final class ReferenceLookupDelegate {
6464

65+
private static final Document NO_RESULTS_PREDICATE = new Document("_id", new Document("$exists", false));
66+
6567
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
6668
private final SpELContext spELContext;
6769
private final ParameterBindingDocumentCodec codec;
@@ -262,25 +264,32 @@ DocumentReferenceQuery computeFilter(MongoPersistentProperty property, Object so
262264
sort);
263265
}
264266

265-
List<Document> ors = new ArrayList<>();
266-
for (Object entry : (Collection<Object>) value) {
267+
Collection<Object> objects = (Collection<Object>) value;
267268

268-
Document decoded = codec.decode(lookup, bindingContext(property, entry, spELContext));
269-
ors.add(decoded);
269+
if (objects.isEmpty()) {
270+
return new ListDocumentReferenceQuery(NO_RESULTS_PREDICATE, sort);
270271
}
271272

272-
if(ors.isEmpty()) {
273-
return new ListDocumentReferenceQuery(new Document("_id", new Document("$exists", false)), sort);
273+
List<Document> ors = new ArrayList<>(objects.size());
274+
for (Object entry : objects) {
275+
276+
Document decoded = codec.decode(lookup, bindingContext(property, entry, spELContext));
277+
ors.add(decoded);
274278
}
275279

276280
return new ListDocumentReferenceQuery(new Document("$or", ors), sort);
277281
}
278282

279283
if (property.isMap() && value instanceof Map) {
280284

281-
Map<Object, Document> filterMap = new LinkedHashMap<>();
285+
Set<Entry<Object, Object>> entries = ((Map<Object, Object>) value).entrySet();
286+
if (entries.isEmpty()) {
287+
return new MapDocumentReferenceQuery(NO_RESULTS_PREDICATE, sort, Collections.emptyMap());
288+
}
289+
290+
Map<Object, Document> filterMap = new LinkedHashMap<>(entries.size());
282291

283-
for (Entry<Object, Object> entry : ((Map<Object, Object>) value).entrySet()) {
292+
for (Entry<Object, Object> entry : entries) {
284293

285294
Document decoded = codec.decode(lookup, bindingContext(property, entry.getValue(), spELContext));
286295
filterMap.put(entry.getKey(), decoded);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,24 @@ void loadEmptyCollectionReference() {
698698
assertThat(result.simplePreinitializedValueRef).isEmpty();
699699
}
700700

701+
@Test // GH-3805
702+
void loadEmptyMapReference() {
703+
704+
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
705+
706+
// an empty reference array.
707+
Document source = new Document("_id", "id-1").append("value", "v1").append("simplePreinitializedMapRef",
708+
new Document());
709+
710+
template.execute(db -> {
711+
db.getCollection(rootCollectionName).insertOne(source);
712+
return null;
713+
});
714+
715+
CollectionRefRoot result = template.findOne(query(where("id").is("id-1")), CollectionRefRoot.class);
716+
assertThat(result.simplePreinitializedMapRef).isEmpty();
717+
}
718+
701719
@Test // GH-3805
702720
void loadNoExistingCollectionReference() {
703721

@@ -1167,6 +1185,9 @@ static class CollectionRefRoot {
11671185
@DocumentReference(lookup = "{ '_id' : '?#{#target}' }") //
11681186
Map<String, SimpleObjectRef> mapValueRef;
11691187

1188+
@DocumentReference //
1189+
Map<String, SimpleObjectRef> simplePreinitializedMapRef = new LinkedHashMap<>();
1190+
11701191
@Field("simple-value-ref-annotated-field-name") //
11711192
@DocumentReference(lookup = "{ '_id' : '?#{#target}' }") //
11721193
List<SimpleObjectRef> simpleValueRefWithAnnotatedFieldName;

0 commit comments

Comments
 (0)