Skip to content

Commit 828c7e2

Browse files
committed
Polishing.
Move Streamable check to QueryBlocks, move off deprecated API. See #5089 Original pull request: #5090
1 parent 4d94ee1 commit 828c7e2

File tree

9 files changed

+52
-68
lines changed

9 files changed

+52
-68
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/AggregationBlocks.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
4242
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
4343
import org.springframework.data.util.ReflectionUtils;
44-
import org.springframework.data.util.Streamable;
4544
import org.springframework.javapoet.CodeBlock;
4645
import org.springframework.javapoet.CodeBlock.Builder;
4746
import org.springframework.util.ClassUtils;
@@ -146,15 +145,11 @@ CodeBlock build() {
146145
builder.addStatement("return $L.aggregateStream($L, $T.class)", mongoOpsRef, aggregationVariableName,
147146
outputType);
148147
} else {
149-
150-
CodeBlock resultBlock = CodeBlock.of("$L.aggregate($L, $T.class).getMappedResults()", mongoOpsRef,
148+
CodeBlock codeBlock = CodeBlock.of("$L.aggregate($L, $T.class).getMappedResults()", mongoOpsRef,
151149
aggregationVariableName, outputType);
152150

153-
if (queryMethod.getReturnType().getType().equals(Streamable.class)) {
154-
resultBlock = CodeBlock.of("$T.of($L)", Streamable.class, resultBlock);
155-
}
156-
157-
builder.addStatement("return $L", resultBlock);
151+
builder.addStatement("return $L",
152+
MongoCodeBlocks.potentiallyWrapStreamable(context.getMethodReturn(), codeBlock));
158153
}
159154
}
160155
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/DeleteBlocks.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@
1818
import java.util.Optional;
1919

2020
import org.jspecify.annotations.NullUnmarked;
21+
2122
import org.springframework.core.ResolvableType;
2223
import org.springframework.data.mongodb.core.ExecutableRemoveOperation.ExecutableRemove;
2324
import org.springframework.data.mongodb.core.MongoOperations;
2425
import org.springframework.data.mongodb.repository.query.MongoQueryExecution.DeleteExecution;
2526
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
2627
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
28+
import org.springframework.data.repository.aot.generate.MethodReturn;
2729
import org.springframework.javapoet.CodeBlock;
2830
import org.springframework.javapoet.CodeBlock.Builder;
2931
import org.springframework.javapoet.TypeName;
3032
import org.springframework.util.ClassUtils;
31-
import org.springframework.util.ObjectUtils;
3233

3334
/**
3435
* @author Christoph Strobl
@@ -59,12 +60,11 @@ CodeBlock build() {
5960

6061
String mongoOpsRef = context.fieldNameOf(MongoOperations.class);
6162
Builder builder = CodeBlock.builder();
62-
63+
MethodReturn methodReturn = context.getMethodReturn();
6364
Class<?> domainType = context.getRepositoryInformation().getDomainType();
64-
boolean isProjecting = context.getActualReturnType() != null
65-
&& !ObjectUtils.nullSafeEquals(TypeName.get(domainType), context.getActualReturnType());
65+
boolean isProjecting = methodReturn.isProjecting();
6666

67-
Object actualReturnType = isProjecting ? context.getActualReturnType().getType() : domainType;
67+
Object actualReturnType = isProjecting ? methodReturn.getActualTypeName() : domainType;
6868

6969
builder.add("\n");
7070
VariableSnippet remover = Snippet.declare(builder)
@@ -83,7 +83,7 @@ CodeBlock build() {
8383

8484
actualReturnType = ClassUtils.isPrimitiveOrWrapper(context.getMethod().getReturnType())
8585
? TypeName.get(context.getMethod().getReturnType())
86-
: queryMethod.isCollectionQuery() ? context.getReturnTypeName() : actualReturnType;
86+
: queryMethod.isCollectionQuery() ? methodReturn.getTypeName() : actualReturnType;
8787

8888
if (ClassUtils.isVoidType(context.getMethod().getReturnType())) {
8989
builder.addStatement("new $T($L, $T.$L).execute($L)", DeleteExecution.class, remover.getVariableName(),

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/GeoBlocks.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.data.mongodb.core.query.NearQuery;
2525
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
2626
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
27+
import org.springframework.data.repository.aot.generate.MethodReturn;
2728
import org.springframework.data.support.PageableExecutionUtils;
2829
import org.springframework.javapoet.CodeBlock;
2930
import org.springframework.util.ClassUtils;
@@ -117,12 +118,13 @@ CodeBlock build() {
117118

118119
CodeBlock.Builder builder = CodeBlock.builder();
119120
builder.add("\n");
121+
MethodReturn methodReturn = context.getMethodReturn();
120122

121123
VariableSnippet queryExecutor = Snippet.declare(builder).variable(context.localVariable("nearFinder")).as(
122124
"$L.query($T.class).near($L)", context.fieldNameOf(MongoOperations.class),
123125
context.getRepositoryInformation().getDomainType(), queryVariableName);
124126

125-
if (ClassUtils.isAssignable(GeoPage.class, context.getReturnType().getRawClass())) {
127+
if (ClassUtils.isAssignable(GeoPage.class, methodReturn.toClass())) {
126128

127129
VariableSnippet geoResult = Snippet.declare(builder).variable(context.localVariable("geoResult")).as("$L.all()",
128130
queryExecutor.getVariableName());
@@ -137,7 +139,7 @@ CodeBlock build() {
137139

138140
builder.addStatement("return new $T<>($L, $L, $L.getTotalElements())", GeoPage.class,
139141
geoResult.getVariableName(), context.getPageableParameterName(), resultPage.getVariableName());
140-
} else if (ClassUtils.isAssignable(GeoResults.class, context.getReturnType().getRawClass())) {
142+
} else if (ClassUtils.isAssignable(GeoResults.class, methodReturn.toClass())) {
141143
builder.addStatement("return $L.all()", queryExecutor.getVariableName());
142144
} else {
143145
builder.addStatement("return $L.all().getContent()", queryExecutor.getVariableName());

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/MongoCodeBlocks.java

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
3535
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
3636
import org.springframework.data.repository.aot.generate.ExpressionMarker;
37+
import org.springframework.data.repository.aot.generate.MethodReturn;
38+
import org.springframework.data.util.Streamable;
3739
import org.springframework.javapoet.CodeBlock;
3840
import org.springframework.javapoet.CodeBlock.Builder;
3941
import org.springframework.util.NumberUtils;
@@ -98,7 +100,6 @@ static DeleteExecutionCodeBlockBuilder deleteExecutionBlockBuilder(AotQueryMetho
98100
* @return
99101
*/
100102
static UpdateCodeBlockBuilder updateBlockBuilder(AotQueryMethodGenerationContext context) {
101-
102103
return new UpdateCodeBlockBuilder(context);
103104
}
104105

@@ -111,44 +112,27 @@ static UpdateCodeBlockBuilder updateBlockBuilder(AotQueryMethodGenerationContext
111112
*/
112113
static UpdateExecutionCodeBlockBuilder updateExecutionBlockBuilder(AotQueryMethodGenerationContext context,
113114
MongoQueryMethod queryMethod) {
114-
115115
return new UpdateExecutionCodeBlockBuilder(context, queryMethod);
116116
}
117117

118118
/**
119119
* Builder for generating aggregation (pipeline) parsing {@link CodeBlock}.
120-
*
121-
* @param context
122-
* @param simpleTypeHolder
123-
* @param queryMethod
124-
* @return
125120
*/
126121
static AggregationCodeBlockBuilder aggregationBlockBuilder(AotQueryMethodGenerationContext context,
127-
SimpleTypeHolder simpleTypeHolder,
128-
MongoQueryMethod queryMethod) {
122+
SimpleTypeHolder simpleTypeHolder, MongoQueryMethod queryMethod) {
129123
return new AggregationCodeBlockBuilder(context, simpleTypeHolder, queryMethod);
130124
}
131125

132126
/**
133127
* Builder for generating aggregation execution {@link CodeBlock}.
134-
*
135-
* @param context
136-
* @param simpleTypeHolder
137-
* @param queryMethod
138-
* @return
139128
*/
140129
static AggregationExecutionCodeBlockBuilder aggregationExecutionBlockBuilder(AotQueryMethodGenerationContext context,
141-
SimpleTypeHolder simpleTypeHolder,
142-
MongoQueryMethod queryMethod) {
130+
SimpleTypeHolder simpleTypeHolder, MongoQueryMethod queryMethod) {
143131
return new AggregationExecutionCodeBlockBuilder(context, simpleTypeHolder, queryMethod);
144132
}
145133

146134
/**
147135
* Builder for generating {@link org.springframework.data.mongodb.core.query.NearQuery} {@link CodeBlock}.
148-
*
149-
* @param context
150-
* @param queryMethod
151-
* @return
152136
*/
153137
static GeoNearCodeBlockBuilder geoNearBlockBuilder(AotQueryMethodGenerationContext context,
154138
MongoQueryMethod queryMethod) {
@@ -159,12 +143,8 @@ static GeoNearCodeBlockBuilder geoNearBlockBuilder(AotQueryMethodGenerationConte
159143
/**
160144
* Builder for generating {@link org.springframework.data.mongodb.core.query.NearQuery} execution {@link CodeBlock}
161145
* that can return {@link org.springframework.data.geo.GeoResults}.
162-
*
163-
* @param context
164-
* @return
165146
*/
166147
static GeoNearExecutionCodeBlockBuilder geoNearExecutionBlockBuilder(AotQueryMethodGenerationContext context) {
167-
168148
return new GeoNearExecutionCodeBlockBuilder(context);
169149
}
170150

@@ -205,6 +185,7 @@ static CodeBlock renderExpressionToDocument(@Nullable String source, String vari
205185

206186
static CodeBlock evaluateNumberPotentially(String value, Class<? extends Number> targetType,
207187
AotQueryMethodGenerationContext context) {
188+
208189
try {
209190
Number number = NumberUtils.parseNumber(value, targetType);
210191
return CodeBlock.of("$L", number);
@@ -251,4 +232,15 @@ static void appendReadPreference(AotQueryMethodGenerationContext context, Builde
251232
readPreference);
252233
}
253234
}
235+
236+
/**
237+
* Wraps the given {@link CodeBlock} representing an {@link Iterable} into a {@link Streamable} if the
238+
* {@link MethodReturn} indicates so.
239+
*/
240+
public static CodeBlock potentiallyWrapStreamable(MethodReturn methodReturn, CodeBlock returningIterable) {
241+
return methodReturn.toClass().equals(Streamable.class)
242+
? CodeBlock.of("$T.of($L)", Streamable.class, returningIterable)
243+
: returningIterable;
244+
}
245+
254246
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/QueryBlocks.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.bson.Document;
2222
import org.jspecify.annotations.NullUnmarked;
23+
2324
import org.springframework.core.annotation.MergedAnnotation;
2425
import org.springframework.data.domain.ScrollPosition;
2526
import org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery;
@@ -33,11 +34,10 @@
3334
import org.springframework.data.mongodb.repository.query.MongoQueryExecution.SlicedExecution;
3435
import org.springframework.data.mongodb.repository.query.MongoQueryMethod;
3536
import org.springframework.data.repository.aot.generate.AotQueryMethodGenerationContext;
37+
import org.springframework.data.repository.aot.generate.MethodReturn;
3638
import org.springframework.data.util.Lazy;
37-
import org.springframework.data.util.Streamable;
3839
import org.springframework.javapoet.CodeBlock;
3940
import org.springframework.javapoet.CodeBlock.Builder;
40-
import org.springframework.javapoet.TypeName;
4141
import org.springframework.util.ClassUtils;
4242
import org.springframework.util.NumberUtils;
4343
import org.springframework.util.StringUtils;
@@ -69,14 +69,15 @@ QueryExecutionCodeBlockBuilder forQuery(QueryInteraction query) {
6969

7070
CodeBlock build() {
7171

72+
MethodReturn methodReturn = context.getMethodReturn();
7273
String mongoOpsRef = context.fieldNameOf(MongoOperations.class);
7374

7475
Builder builder = CodeBlock.builder();
7576

7677
boolean isProjecting = context.getReturnedType().isProjecting();
7778
Class<?> domainType = context.getRepositoryInformation().getDomainType();
7879
Object actualReturnType = queryMethod.getParameters().hasDynamicProjection() || isProjecting
79-
? TypeName.get(context.getActualReturnType().getType())
80+
? methodReturn.getActualTypeName()
8081
: domainType;
8182

8283
builder.add("\n");
@@ -105,10 +106,10 @@ CodeBlock build() {
105106
terminatingMethod = "stream()";
106107
} else {
107108
if (query.getQuery().isLimited()) {
108-
terminatingMethod = Optional.class.isAssignableFrom(context.getReturnType().toClass()) ? "first()"
109+
terminatingMethod = Optional.class.isAssignableFrom(methodReturn.toClass()) ? "first()"
109110
: "firstValue()";
110111
} else {
111-
terminatingMethod = Optional.class.isAssignableFrom(context.getReturnType().toClass()) ? "one()"
112+
terminatingMethod = Optional.class.isAssignableFrom(methodReturn.toClass()) ? "one()"
112113
: "oneValue()";
113114
}
114115
}
@@ -139,7 +140,8 @@ CodeBlock build() {
139140
}
140141
}
141142
} else {
142-
if (query.isCount() && !ClassUtils.isAssignable(Long.class, context.getActualReturnType().getRawClass())) {
143+
144+
if (query.isCount() && !ClassUtils.isAssignable(Long.class, methodReturn.getActualReturnClass())) {
143145

144146
Class<?> returnType = ClassUtils.resolvePrimitiveIfNecessary(queryMethod.getReturnedObjectType());
145147
builder.addStatement("return $T.convertNumberToTargetClass($L.matching($L).$L, $T.class)", NumberUtils.class,
@@ -150,11 +152,7 @@ CodeBlock build() {
150152
CodeBlock resultBlock = CodeBlock.of("$L.matching($L).$L", context.localVariable("finder"), query.name(),
151153
terminatingMethod);
152154

153-
if (queryMethod.getReturnType().getType().equals(Streamable.class)) {
154-
resultBlock = CodeBlock.of("$T.of($L)", Streamable.class, resultBlock);
155-
}
156-
157-
builder.addStatement("return $L", resultBlock);
155+
builder.addStatement("return $L", MongoCodeBlocks.potentiallyWrapStreamable(methodReturn, resultBlock));
158156
}
159157
}
160158

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/VectorSearchBlocks.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ private ExpressionSnippet getSort() {
166166
builder.indent();
167167

168168
builder.add("$1T $4L = $5L.getMappedObject(parse($2S), $3T.class);\n", Document.class, filter.getSortString(),
169-
context.getActualReturnType().getType(), mappedSort, ctx);
169+
context.getMethodReturn().getActualClassName(), mappedSort, ctx);
170170
builder.add("return new $1T($2S, $3L.append(\"__score__\", -1));\n", Document.class, "$sort", mappedSort);
171171
builder.unindent();
172-
builder.add("};");
172+
builder.add("}");
173173

174174
return new ExpressionSnippet(builder.build());
175175
}

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@
3636
import org.bson.types.ObjectId;
3737
import org.jspecify.annotations.Nullable;
3838
import org.junit.jupiter.api.BeforeEach;
39+
import org.junit.jupiter.api.Disabled;
3940
import org.junit.jupiter.api.Test;
40-
import org.junit.jupiter.api.condition.DisabledForJreRange;
41-
import org.junit.jupiter.api.condition.JRE;
4241
import org.junit.jupiter.api.extension.ExtendWith;
4342
import org.mockito.Mock;
4443
import org.mockito.Mockito;
@@ -186,7 +185,7 @@ void lazyLoadingProxyForLazyDbRefOnInterface() {
186185
}
187186

188187
@Test // DATAMONGO-348
189-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg; ArrayList require to open java.util.")
188+
@Disabled("Class Proxies for eg; ArrayList require to open java.util.")
190189
void lazyLoadingProxyForLazyDbRefOnConcreteCollection() {
191190

192191
String id = "42";
@@ -514,7 +513,7 @@ void shouldNotEagerlyResolveIdPropertyWithPropertyAccess() {
514513
}
515514

516515
@Test // DATAMONGO-1076
517-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg; ArrayList require to open java.util.")
516+
@Disabled("Class Proxies for eg; ArrayList require to open java.util.")
518517
void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() throws Exception {
519518

520519
MongoPersistentEntity<?> entity = mappingContext
@@ -533,7 +532,7 @@ void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() thr
533532
}
534533

535534
@Test // DATAMONGO-1194
536-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg; ArrayList require to open java.util.")
535+
@Disabled("Class Proxies for eg; ArrayList require to open java.util.")
537536
void shouldBulkFetchListOfReferences() {
538537

539538
String id1 = "1";
@@ -584,7 +583,7 @@ void shouldBulkFetchSetOfReferencesForConstructorCreation() {
584583
}
585584

586585
@Test // DATAMONGO-1194
587-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg; ArrayList require to open java.util.")
586+
@Disabled("Class Proxies for eg; ArrayList require to open java.util.")
588587
void shouldFallbackToOneByOneFetchingWhenElementsInListOfReferencesPointToDifferentCollections() {
589588

590589
String id1 = "1";

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@
2222
import nl.jqno.equalsverifier.Warning;
2323

2424
import org.bson.Document;
25+
import org.junit.jupiter.api.Disabled;
2526
import org.junit.jupiter.api.Test;
2627

27-
import org.junit.jupiter.api.condition.DisabledForJreRange;
28-
import org.junit.jupiter.api.condition.JRE;
2928
import org.springframework.data.domain.Sort;
3029
import org.springframework.data.domain.Sort.Direction;
3130

@@ -66,7 +65,7 @@ public void overridesSortCorrectly() {
6665
}
6766

6867
@Test // DATAMONGO-1093
69-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "EqualsVerifier uses reflection on Optional")
68+
@Disabled("EqualsVerifier uses reflection on Optional")
7069
public void equalsContract() {
7170

7271
BasicQuery query1 = new BasicQuery("{ \"name\" : \"Thomas\"}", "{\"name\":1, \"age\":1}");

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryLazyLoadingIntegrationTests.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,18 @@
1515
*/
1616
package org.springframework.data.mongodb.repository;
1717

18-
import static org.assertj.core.api.Assertions.assertThat;
19-
import static org.assertj.core.api.Assertions.assertThatNoException;
20-
import static org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils.assertProxyIsResolved;
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.springframework.data.mongodb.core.convert.LazyLoadingTestUtils.*;
2120

2221
import java.util.ArrayList;
2322
import java.util.Arrays;
2423
import java.util.List;
2524

2625
import org.junit.jupiter.api.BeforeEach;
26+
import org.junit.jupiter.api.Disabled;
2727
import org.junit.jupiter.api.Test;
28-
import org.junit.jupiter.api.condition.DisabledForJreRange;
29-
import org.junit.jupiter.api.condition.JRE;
3028
import org.junit.jupiter.api.extension.ExtendWith;
29+
3130
import org.springframework.beans.factory.annotation.Autowired;
3231
import org.springframework.data.mongodb.core.MongoOperations;
3332
import org.springframework.test.context.ContextConfiguration;
@@ -78,7 +77,7 @@ public void shouldLoadAssociationWithDbRefOnInterfaceAndLazyLoadingEnabled() thr
7877
}
7978

8079
@Test // DATAMONGO-348
81-
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg; ArrayList require to open java.util.")
80+
@Disabled("Class Proxies for eg; ArrayList require to open java.util.")
8281
public void shouldLoadAssociationWithDbRefOnConcreteCollectionAndLazyLoadingEnabled() {
8382

8483
User thomas = new User();

0 commit comments

Comments
 (0)