Skip to content

Commit 404fde7

Browse files
committed
Add copy constructor to BasicQuery.
Removes the need for proxying. Original pull request: #4747 See #4744
1 parent 24ea7ac commit 404fde7

File tree

5 files changed

+44
-67
lines changed

5 files changed

+44
-67
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java

+15
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ public BasicQuery(Document queryObject, Document fieldsObject) {
8585
this.sortObject = new Document();
8686
}
8787

88+
/**
89+
* Create a BasicQuery given a {@link Query}. The resulting query is a copy of {@link Query}.
90+
*
91+
* @param query the query to copy.
92+
* @since 4.4
93+
*/
94+
public BasicQuery(Query query) {
95+
96+
super(query);
97+
this.queryObject = query.getQueryObject();
98+
this.setFieldsObject(query.getFieldsObject());
99+
this.setSortObject(query.getSortObject());
100+
this.setMeta(query.getMeta());
101+
}
102+
88103
@Override
89104
public Query addCriteria(CriteriaDefinition criteria) {
90105

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java

+14
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ public class Query implements ReadConcernAware, ReadPreferenceAware {
7979

8080
private Optional<Collation> collation = Optional.empty();
8181

82+
Query(Query query) {
83+
this.restrictedTypes = query.restrictedTypes;
84+
this.fieldSpec = query.fieldSpec;
85+
this.sort = query.sort;
86+
this.limit = query.limit;
87+
this.skip = query.skip;
88+
this.keysetScrollPosition = query.keysetScrollPosition;
89+
this.readConcern = query.readConcern;
90+
this.readPreference = query.readPreference;
91+
this.hint = query.hint;
92+
this.meta = query.meta;
93+
this.collation = query.collation;
94+
}
95+
8296
/**
8397
* Static factory method to create a {@link Query} using the provided {@link CriteriaDefinition}.
8498
*

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

-15
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424
import org.springframework.aot.hint.RuntimeHintsRegistrar;
2525
import org.springframework.aot.hint.TypeReference;
2626
import org.springframework.data.mongodb.aot.MongoAotPredicates;
27-
import org.springframework.data.mongodb.aot.MongoAotReflectionHelper;
28-
import org.springframework.data.mongodb.core.query.BasicQuery;
29-
import org.springframework.data.mongodb.core.query.Query;
30-
import org.springframework.data.mongodb.repository.query.QueryUtils;
3127
import org.springframework.data.mongodb.repository.support.CrudMethodMetadata;
3228
import org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor;
3329
import org.springframework.data.mongodb.repository.support.ReactiveQuerydslMongoPredicateExecutor;
@@ -49,8 +45,6 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
4945
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
5046
MemberCategory.INVOKE_PUBLIC_METHODS));
5147

52-
registerHintsForDefaultSorting(hints, classLoader);
53-
5448
if (isAopPresent(classLoader)) {
5549

5650
// required for pushing ReadPreference,... into the default repository implementation
@@ -99,13 +93,4 @@ private static boolean isAopPresent(@Nullable ClassLoader classLoader) {
9993
return ClassUtils.isPresent("org.springframework.aop.Pointcut", classLoader);
10094
}
10195

102-
private static void registerHintsForDefaultSorting(RuntimeHints hints, @Nullable ClassLoader classLoader) {
103-
104-
List<TypeReference> types = List.of(TypeReference.of(Query.class), //
105-
TypeReference.of(QueryUtils.queryProxyType(Query.class, classLoader)), //
106-
TypeReference.of(BasicQuery.class), //
107-
TypeReference.of(QueryUtils.queryProxyType(BasicQuery.class, classLoader)));
108-
109-
hints.reflection().registerTypes(types, MongoAotReflectionHelper::cglibProxyReflectionMemberAccess);
110-
}
11196
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.bson.Document;
2222
import org.bson.codecs.configuration.CodecRegistry;
23+
2324
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
2425
import org.springframework.data.mongodb.core.ExecutableFindOperation.ExecutableFind;
2526
import org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery;
@@ -155,7 +156,7 @@ protected Object doExecute(MongoQueryMethod method, ResultProcessor processor, C
155156
* @since 4.2
156157
*/
157158
private Query applyAnnotatedReadPreferenceIfPresent(Query query) {
158-
159+
159160
if (!method.hasAnnotatedReadPreference()) {
160161
return query;
161162
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/QueryUtils.java

+13-51
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,15 @@
1818
import java.util.Arrays;
1919
import java.util.List;
2020

21-
import org.aopalliance.intercept.MethodInterceptor;
22-
import org.aopalliance.intercept.MethodInvocation;
2321
import org.apache.commons.logging.Log;
2422
import org.apache.commons.logging.LogFactory;
2523
import org.bson.Document;
26-
import org.springframework.aop.framework.ProxyFactory;
24+
25+
import org.springframework.data.mongodb.core.query.BasicQuery;
2726
import org.springframework.data.mongodb.core.query.Collation;
2827
import org.springframework.data.mongodb.core.query.Query;
2928
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
3029
import org.springframework.expression.ExpressionParser;
31-
import org.springframework.lang.NonNull;
3230
import org.springframework.lang.Nullable;
3331
import org.springframework.util.ClassUtils;
3432

@@ -41,7 +39,7 @@
4139
* @since 2.1
4240
* @currentRead Assassin's Apprentice - Robin Hobb
4341
*/
44-
public class QueryUtils {
42+
class QueryUtils {
4543

4644
protected static final Log LOGGER = LogFactory.getLog(QueryUtils.class);
4745

@@ -53,25 +51,19 @@ public class QueryUtils {
5351
* @param defaultSort the default sort expression to apply to the query.
5452
* @return the query having the given {@code sort} applied.
5553
*/
56-
public static Query decorateSort(Query query, Document defaultSort) {
54+
static Query decorateSort(Query query, Document defaultSort) {
5755

5856
if (defaultSort.isEmpty()) {
5957
return query;
6058
}
6159

62-
ProxyFactory factory = prepareQueryProxy(query.getClass(), defaultSort);
63-
factory.setTarget(query);
64-
return (Query) factory.getProxy(query.getClass().getClassLoader());
65-
}
60+
BasicQuery defaultSortQuery = query instanceof BasicQuery bq ? bq : new BasicQuery(query);
6661

67-
/**
68-
* Decorate {@link Query} and add a default sort expression to the given {@link Query}. Attributes of the given
69-
* {@code sort} may be overwritten by the sort explicitly defined by the {@link Query} itself.
70-
*
71-
* @param classLoader the {@link ClassLoader} to use for generating the proxy type with.
72-
*/
73-
public static Class<?> queryProxyType(Class<? extends Query> baseType, ClassLoader classLoader) {
74-
return prepareQueryProxy(baseType, new Document()).getProxyClass(classLoader);
62+
Document combinedSort = new Document(defaultSort);
63+
combinedSort.putAll(defaultSortQuery.getSortObject());
64+
defaultSortQuery.setSortObject(combinedSort);
65+
66+
return defaultSortQuery;
7567
}
7668

7769
/**
@@ -116,48 +108,18 @@ static int indexOfAssignableParameter(Class<?> type, Class<?>[] parameters) {
116108
*/
117109
static int indexOfAssignableParameter(Class<?> type, List<Class<?>> parameters) {
118110

119-
if(parameters.isEmpty()) {
111+
if (parameters.isEmpty()) {
120112
return -1;
121113
}
122114

123115
int i = 0;
124-
for(Class<?> parameterType : parameters) {
125-
if(ClassUtils.isAssignable(type, parameterType)) {
116+
for (Class<?> parameterType : parameters) {
117+
if (ClassUtils.isAssignable(type, parameterType)) {
126118
return i;
127119
}
128120
i++;
129121
}
130122
return -1;
131123
}
132124

133-
private static ProxyFactory prepareQueryProxy(Class<? extends Query> query, Document defaultSort) {
134-
135-
ProxyFactory factory = new ProxyFactory();
136-
factory.setTargetClass(query);
137-
factory.addAdvice(new DefaultSortingInterceptor(defaultSort));
138-
factory.setInterfaces(new Class[0]);
139-
return factory;
140-
}
141-
142-
static class DefaultSortingInterceptor implements MethodInterceptor {
143-
144-
private final Document defaultSort;
145-
146-
public DefaultSortingInterceptor(Document defaultSort) {
147-
this.defaultSort = defaultSort;
148-
}
149-
150-
@Nullable
151-
@Override
152-
public Object invoke(@NonNull MethodInvocation invocation) throws Throwable {
153-
154-
if (!invocation.getMethod().getName().equals("getSortObject")) {
155-
return invocation.proceed();
156-
}
157-
158-
Document combinedSort = new Document(defaultSort);
159-
combinedSort.putAll((Document) invocation.proceed());
160-
return combinedSort;
161-
}
162-
}
163125
}

0 commit comments

Comments
 (0)