diff --git a/pom.xml b/pom.xml
index f518c186f5..ff741d5be9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4744-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index a3dc49f892..973dbb4522 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4744-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index e33930bfd2..3a275dc0ab 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4744-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index fafe9c8793..939d481f5e 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.4.0-SNAPSHOT
+ 4.4.x-GH-4744-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/LazyLoadingProxyAotProcessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/LazyLoadingProxyAotProcessor.java
index 09080c32d5..530ffce510 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/LazyLoadingProxyAotProcessor.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/LazyLoadingProxyAotProcessor.java
@@ -24,7 +24,6 @@
import java.util.Set;
import org.springframework.aot.generate.GenerationContext;
-import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.TypeReference;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.MergedAnnotations;
@@ -77,8 +76,7 @@ public void registerLazyLoadingProxyIfNeeded(Class> type, GenerationContext ge
LazyLoadingInterceptor::none);
// see: spring-projects/spring-framework/issues/29309
- generationContext.getRuntimeHints().reflection().registerType(proxyClass,
- MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.DECLARED_FIELDS);
+ generationContext.getRuntimeHints().reflection().registerType(proxyClass, MongoAotReflectionHelper::cglibProxyReflectionMemberAccess);
}
});
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotReflectionHelper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotReflectionHelper.java
new file mode 100644
index 0000000000..e3d3a30336
--- /dev/null
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoAotReflectionHelper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.mongodb.aot;
+
+import org.springframework.aot.hint.MemberCategory;
+import org.springframework.aot.hint.TypeHint.Builder;
+
+/**
+ * @author Christoph Strobl
+ */
+public final class MongoAotReflectionHelper {
+
+ public static void cglibProxyReflectionMemberAccess(Builder builder) {
+
+ builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS,
+ MemberCategory.DECLARED_FIELDS);
+ }
+}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
index b381a21593..79ceeda95e 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
@@ -85,6 +85,20 @@ public BasicQuery(Document queryObject, Document fieldsObject) {
this.sortObject = new Document();
}
+ /**
+ * Create a BasicQuery given a {@link Query}. The resulting query is a copy of {@link Query}.
+ *
+ * @param query
+ */
+ public BasicQuery(Query query) {
+
+ super(query);
+ this.queryObject = query.getQueryObject();
+ this.setFieldsObject(query.getFieldsObject());
+ this.setSortObject(query.getSortObject());
+ this.setMeta(query.getMeta());
+ }
+
@Override
public Query addCriteria(CriteriaDefinition criteria) {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
index 2b307f15c7..d79b22aef7 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
@@ -79,6 +79,20 @@ public class Query implements ReadConcernAware, ReadPreferenceAware {
private Optional collation = Optional.empty();
+ Query(Query query) {
+ this.restrictedTypes = query.restrictedTypes;
+ this.fieldSpec = query.fieldSpec;
+ this.sort = query.sort;
+ this.limit = query.limit;
+ this.skip = query.skip;
+ this.keysetScrollPosition = query.keysetScrollPosition;
+ this.readConcern = query.readConcern;
+ this.readPreference = query.readPreference;
+ this.hint = query.hint;
+ this.meta = query.meta;
+ this.collation = query.collation;
+ }
+
/**
* Static factory method to create a {@link Query} using the provided {@link CriteriaDefinition}.
*
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java
index 203e5e9810..46e6c9044c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/aot/RepositoryRuntimeHints.java
@@ -92,4 +92,5 @@ private static void registerQuerydslHints(RuntimeHints hints, @Nullable ClassLoa
private static boolean isAopPresent(@Nullable ClassLoader classLoader) {
return ClassUtils.isPresent("org.springframework.aop.Pointcut", classLoader);
}
+
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java
index 52eef58340..61bfa0f7b3 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java
@@ -20,6 +20,7 @@
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistry;
+
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.data.mongodb.core.ExecutableFindOperation.ExecutableFind;
import org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery;
@@ -155,7 +156,7 @@ protected Object doExecute(MongoQueryMethod method, ResultProcessor processor, C
* @since 4.2
*/
private Query applyAnnotatedReadPreferenceIfPresent(Query query) {
-
+
if (!method.hasAnnotatedReadPreference()) {
return query;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java
index 1aab34055a..c6ad7a634f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java
@@ -18,9 +18,11 @@
import java.util.Arrays;
import java.util.List;
-import org.aopalliance.intercept.MethodInterceptor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.bson.Document;
-import org.springframework.aop.framework.ProxyFactory;
+
+import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
@@ -39,6 +41,8 @@
*/
class QueryUtils {
+ protected static final Log LOGGER = LogFactory.getLog(QueryUtils.class);
+
/**
* Decorate {@link Query} and add a default sort expression to the given {@link Query}. Attributes of the given
* {@code sort} may be overwritten by the sort explicitly defined by the {@link Query} itself.
@@ -53,20 +57,13 @@ static Query decorateSort(Query query, Document defaultSort) {
return query;
}
- ProxyFactory factory = new ProxyFactory(query);
- factory.addAdvice((MethodInterceptor) invocation -> {
+ BasicQuery defaultSortQuery = query instanceof BasicQuery bq ? bq : new BasicQuery(query);
- if (!invocation.getMethod().getName().equals("getSortObject")) {
- return invocation.proceed();
- }
+ Document combinedSort = new Document(defaultSort);
+ combinedSort.putAll(defaultSortQuery.getSortObject());
+ defaultSortQuery.setSortObject(combinedSort);
- Document combinedSort = new Document(defaultSort);
- combinedSort.putAll((Document) invocation.proceed());
- return combinedSort;
- });
- factory.setInterfaces(new Class[0]);
-
- return (Query) factory.getProxy(query.getClass().getClassLoader());
+ return defaultSortQuery;
}
/**
@@ -111,17 +108,18 @@ static int indexOfAssignableParameter(Class> type, Class>[] parameters) {
*/
static int indexOfAssignableParameter(Class> type, List> parameters) {
- if(parameters.isEmpty()) {
+ if (parameters.isEmpty()) {
return -1;
}
int i = 0;
- for(Class> parameterType : parameters) {
- if(ClassUtils.isAssignable(type, parameterType)) {
+ for (Class> parameterType : parameters) {
+ if (ClassUtils.isAssignable(type, parameterType)) {
return i;
}
i++;
}
return -1;
}
+
}