Polishing.

Extract query that yields no hits into constant. Guard Map-typed reference properties against empty $or.

See #3805
Original pull request: #3807.
This commit is contained in:
Mark Paluch
2021-09-08 14:18:17 +02:00
parent 4e960a9682
commit 270456ed81
2 changed files with 38 additions and 8 deletions

View File

@@ -62,6 +62,8 @@ import com.mongodb.client.MongoCollection;
*/
public final class ReferenceLookupDelegate {
private static final Document NO_RESULTS_PREDICATE = new Document("_id", new Document("$exists", false));
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
private final SpELContext spELContext;
private final ParameterBindingDocumentCodec codec;
@@ -262,25 +264,32 @@ public final class ReferenceLookupDelegate {
sort);
}
List<Document> ors = new ArrayList<>();
for (Object entry : (Collection<Object>) value) {
Collection<Object> objects = (Collection<Object>) value;
if (objects.isEmpty()) {
return new ListDocumentReferenceQuery(NO_RESULTS_PREDICATE, sort);
}
List<Document> ors = new ArrayList<>(objects.size());
for (Object entry : objects) {
Document decoded = codec.decode(lookup, bindingContext(property, entry, spELContext));
ors.add(decoded);
}
if(ors.isEmpty()) {
return new ListDocumentReferenceQuery(new Document("_id", new Document("$exists", false)), sort);
}
return new ListDocumentReferenceQuery(new Document("$or", ors), sort);
}
if (property.isMap() && value instanceof Map) {
Map<Object, Document> filterMap = new LinkedHashMap<>();
Set<Entry<Object, Object>> entries = ((Map<Object, Object>) value).entrySet();
if (entries.isEmpty()) {
return new MapDocumentReferenceQuery(NO_RESULTS_PREDICATE, sort, Collections.emptyMap());
}
for (Entry<Object, Object> entry : ((Map<Object, Object>) value).entrySet()) {
Map<Object, Document> filterMap = new LinkedHashMap<>(entries.size());
for (Entry<Object, Object> entry : entries) {
Document decoded = codec.decode(lookup, bindingContext(property, entry.getValue(), spELContext));
filterMap.put(entry.getKey(), decoded);

View File

@@ -698,6 +698,24 @@ public class MongoTemplateDocumentReferenceTests {
assertThat(result.simplePreinitializedValueRef).isEmpty();
}
@Test // GH-3805
void loadEmptyMapReference() {
String rootCollectionName = template.getCollectionName(CollectionRefRoot.class);
// an empty reference array.
Document source = new Document("_id", "id-1").append("value", "v1").append("simplePreinitializedMapRef",
new Document());
template.execute(db -> {
db.getCollection(rootCollectionName).insertOne(source);
return null;
});
CollectionRefRoot result = template.findOne(query(where("id").is("id-1")), CollectionRefRoot.class);
assertThat(result.simplePreinitializedMapRef).isEmpty();
}
@Test // GH-3805
void loadNoExistingCollectionReference() {
@@ -1167,6 +1185,9 @@ public class MongoTemplateDocumentReferenceTests {
@DocumentReference(lookup = "{ '_id' : '?#{#target}' }") //
Map<String, SimpleObjectRef> mapValueRef;
@DocumentReference //
Map<String, SimpleObjectRef> simplePreinitializedMapRef = new LinkedHashMap<>();
@Field("simple-value-ref-annotated-field-name") //
@DocumentReference(lookup = "{ '_id' : '?#{#target}' }") //
List<SimpleObjectRef> simpleValueRefWithAnnotatedFieldName;