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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user