Skip reference lookup when DocumentReference resolves to an empty collection.

Fixes #4612
Original pull request: #4613
This commit is contained in:
Stefan Bildl
2024-01-12 14:48:54 +01:00
committed by Mark Paluch
parent 37aaf53658
commit 4ec995f9c8
2 changed files with 21 additions and 9 deletions

View File

@@ -60,6 +60,7 @@ import com.mongodb.client.MongoCollection;
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Stefan Bildl
* @since 3.3
*/
public final class ReferenceLookupDelegate {
@@ -106,6 +107,11 @@ public final class ReferenceLookupDelegate {
Object value = source instanceof DocumentReferenceSource documentReferenceSource ? documentReferenceSource.getTargetSource()
: source;
// GH-4612 no need to query database if target collection is empty
if (value != null && property.isCollectionLike() && (value instanceof Collection<?> c) && c.isEmpty()) {
return new ArrayList<>();
}
DocumentReferenceQuery filter = computeFilter(property, source, spELContext);
ReferenceCollection referenceCollection = computeReferenceContext(property, value, spELContext);

View File

@@ -15,17 +15,11 @@
*/
package org.springframework.data.mongodb.core.convert;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.SpELContext;
import org.springframework.data.mongodb.core.convert.ReferenceResolver.MongoEntityReader;
@@ -33,7 +27,11 @@ import org.springframework.data.mongodb.core.mapping.DocumentReference;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
/**
* Unit tests for {@link ReferenceLookupDelegate}.
@@ -52,9 +50,17 @@ class ReferenceLookupDelegateUnitTests {
@BeforeEach
void beforeEach() {
lookupDelegate = new ReferenceLookupDelegate(mappingContext, spELContext);
when(spELContext.getParser()).thenReturn(new SpelExpressionParser());
}
@Test // GH-4612
void shouldResolveEmptyListOnEmptyTargetCollection() {
MongoPersistentProperty property = mock(MongoPersistentProperty.class);
ReferenceLookupDelegate.LookupFunction lookupFunction = mock(ReferenceLookupDelegate.LookupFunction.class);
when(property.isCollectionLike()).thenReturn(true);
lookupDelegate.readReference(property, Collections.emptyList(), lookupFunction, entityReader);
verify(lookupFunction, never()).apply(any(), any());
}
@Test // GH-3842