Skip to content

Commit 740a206

Browse files
mp911dechristophstrobl
authored andcommitted
Adopt to AOT changes in Commons.
Closes: #4964
1 parent 1919dad commit 740a206

18 files changed

+1026
-59
lines changed

spring-data-mongodb/pom.xml

+7
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@
140140
<optional>true</optional>
141141
</dependency>
142142

143+
<dependency>
144+
<groupId>net.javacrumbs.json-unit</groupId>
145+
<artifactId>json-unit-assertj</artifactId>
146+
<version>4.1.0</version>
147+
<scope>test</scope>
148+
</dependency>
149+
143150
<!-- CDI -->
144151
<!-- Dependency order required to build against CDI 1.0 and test with CDI 2.0 -->
145152
<dependency>

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2424
import org.springframework.core.annotation.AnnotationAttributes;
2525
import org.springframework.data.config.ParsingUtils;
26-
import org.springframework.data.mongodb.repository.aot.AotMongoRepositoryPostProcessor;
2726
import org.springframework.data.mongodb.core.mapping.Document;
2827
import org.springframework.data.mongodb.repository.MongoRepository;
28+
import org.springframework.data.mongodb.repository.aot.AotMongoRepositoryPostProcessor;
2929
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
30+
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
3031
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
3132
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
3233
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
@@ -55,6 +56,12 @@ public String getModulePrefix() {
5556
return "mongo";
5657
}
5758

59+
@Override
60+
public String getRepositoryBaseClassName() {
61+
return SimpleMongoRepository.class.getName();
62+
}
63+
64+
@Override
5865
public String getRepositoryFactoryBeanClassName() {
5966
return MongoRepositoryFactoryBean.class.getName();
6067
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/ReactiveMongoRepositoryConfigurationExtension.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
import org.springframework.data.config.ParsingUtils;
2424
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
2525
import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactoryBean;
26+
import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository;
2627
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
2728
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
2829
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
2930
import org.springframework.data.repository.core.RepositoryMetadata;
31+
3032
import org.w3c.dom.Element;
3133

3234
/**
@@ -47,7 +49,13 @@ public String getModuleName() {
4749
return "Reactive MongoDB";
4850
}
4951

50-
public String getRepositoryFactoryClassName() {
52+
@Override
53+
public String getRepositoryBaseClassName() {
54+
return SimpleReactiveMongoRepository.class.getName();
55+
}
56+
57+
@Override
58+
public String getRepositoryFactoryBeanClassName() {
5159
return ReactiveMongoRepositoryFactoryBean.class.getName();
5260
}
5361

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactory.java

+18-24
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
*/
1616
package org.springframework.data.mongodb.repository.support;
1717

18-
import static org.springframework.data.querydsl.QuerydslUtils.*;
19-
2018
import java.io.Serializable;
2119
import java.lang.reflect.Method;
2220
import java.util.Optional;
2321

2422
import org.jspecify.annotations.Nullable;
23+
2524
import org.springframework.beans.factory.BeanFactory;
26-
import org.springframework.dao.InvalidDataAccessApiUsageException;
2725
import org.springframework.data.mapping.context.MappingContext;
2826
import org.springframework.data.mongodb.core.MongoOperations;
2927
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
@@ -35,7 +33,6 @@
3533
import org.springframework.data.mongodb.repository.query.StringBasedAggregation;
3634
import org.springframework.data.mongodb.repository.query.StringBasedMongoQuery;
3735
import org.springframework.data.projection.ProjectionFactory;
38-
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
3936
import org.springframework.data.repository.core.NamedQueries;
4037
import org.springframework.data.repository.core.RepositoryInformation;
4138
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -60,6 +57,7 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
6057
private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor();
6158
private final MongoOperations operations;
6259
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
60+
private MongoRepositoryFragmentsContributor fragmentsContributor = MongoRepositoryFragmentsContributor.DEFAULT;
6361

6462
/**
6563
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoOperations}.
@@ -76,6 +74,17 @@ public MongoRepositoryFactory(MongoOperations mongoOperations) {
7674
addRepositoryProxyPostProcessor(crudMethodMetadataPostProcessor);
7775
}
7876

77+
/**
78+
* Configures the {@link MongoRepositoryFragmentsContributor} to be used. Defaults to
79+
* {@link MongoRepositoryFragmentsContributor#DEFAULT}.
80+
*
81+
* @param fragmentsContributor
82+
* @since 5.0
83+
*/
84+
public void setFragmentsContributor(MongoRepositoryFragmentsContributor fragmentsContributor) {
85+
this.fragmentsContributor = fragmentsContributor;
86+
}
87+
7988
@Override
8089
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
8190

@@ -99,33 +108,18 @@ protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata
99108
}
100109

101110
/**
102-
* Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add Mongo-specific extensions. Typically
103-
* adds a {@link QuerydslMongoPredicateExecutor} if the repository interface uses Querydsl.
111+
* Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add Mongo-specific extensions.
112+
* Typically, adds a {@link QuerydslMongoPredicateExecutor} if the repository interface uses Querydsl.
104113
* <p>
105-
* Can be overridden by subclasses to customize {@link RepositoryFragments}.
114+
* Built-in fragment contribution can be customized by configuring {@link MongoRepositoryFragmentsContributor}.
106115
*
107116
* @param metadata repository metadata.
108117
* @param operations the MongoDB operations manager.
109-
* @return
118+
* @return {@link RepositoryFragments} to be added to the repository.
110119
* @since 3.2.1
111120
*/
112121
protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata, MongoOperations operations) {
113-
114-
boolean isQueryDslRepository = QUERY_DSL_PRESENT
115-
&& QuerydslPredicateExecutor.class.isAssignableFrom(metadata.getRepositoryInterface());
116-
117-
if (isQueryDslRepository) {
118-
119-
if (metadata.isReactiveRepository()) {
120-
throw new InvalidDataAccessApiUsageException(
121-
"Cannot combine Querydsl and reactive repository support in a single interface");
122-
}
123-
124-
return RepositoryFragments
125-
.just(new QuerydslMongoPredicateExecutor<>(getEntityInformation(metadata.getDomainType()), operations));
126-
}
127-
128-
return RepositoryFragments.empty();
122+
return fragmentsContributor.contribute(metadata, getEntityInformation(metadata.getDomainType()), operations);
129123
}
130124

131125
@Override

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java

+21-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
* {@link org.springframework.beans.factory.FactoryBean} to create {@link MongoRepository} instances.
3131
*
3232
* @author Oliver Gierke
33+
* @author Mark Paluch
3334
*/
3435
@SuppressWarnings("NullAway")
3536
public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
3637
extends RepositoryFactoryBeanSupport<T, S, ID> {
3738

3839
private @Nullable MongoOperations operations;
40+
private MongoRepositoryFragmentsContributor repositoryFragmentsContributor = MongoRepositoryFragmentsContributor.DEFAULT;
3941
private boolean createIndexesForQueryMethods = false;
4042
private boolean mappingContextConfigured = false;
4143

@@ -57,6 +59,22 @@ public void setMongoOperations(MongoOperations operations) {
5759
this.operations = operations;
5860
}
5961

62+
@Override
63+
public MongoRepositoryFragmentsContributor getRepositoryFragmentsContributor() {
64+
return repositoryFragmentsContributor;
65+
}
66+
67+
/**
68+
* Configures the {@link MongoRepositoryFragmentsContributor} to contribute built-in fragment functionality to the
69+
* repository.
70+
*
71+
* @param repositoryFragmentsContributor must not be {@literal null}.
72+
* @since 5.0
73+
*/
74+
public void setRepositoryFragmentsContributor(MongoRepositoryFragmentsContributor repositoryFragmentsContributor) {
75+
this.repositoryFragmentsContributor = repositoryFragmentsContributor;
76+
}
77+
6078
/**
6179
* Configures whether to automatically create indexes for the properties referenced in a query method.
6280
*
@@ -76,7 +94,8 @@ public void setMappingContext(MappingContext<?, ?> mappingContext) {
7694
@Override
7795
protected RepositoryFactorySupport createRepositoryFactory() {
7896

79-
RepositoryFactorySupport factory = getFactoryInstance(operations);
97+
MongoRepositoryFactory factory = getFactoryInstance(operations);
98+
factory.setFragmentsContributor(repositoryFragmentsContributor);
8099

81100
if (createIndexesForQueryMethods) {
82101
factory.addQueryCreationListener(
@@ -92,7 +111,7 @@ protected RepositoryFactorySupport createRepositoryFactory() {
92111
* @param operations
93112
* @return
94113
*/
95-
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
114+
protected MongoRepositoryFactory getFactoryInstance(MongoOperations operations) {
96115
return new MongoRepositoryFactory(operations);
97116
}
98117

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.repository.support;
17+
18+
import org.springframework.data.mongodb.core.MongoOperations;
19+
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
20+
import org.springframework.data.repository.core.RepositoryMetadata;
21+
import org.springframework.data.repository.core.support.RepositoryComposition;
22+
import org.springframework.data.repository.core.support.RepositoryFragmentsContributor;
23+
import org.springframework.util.Assert;
24+
25+
/**
26+
* MongoDB-specific {@link RepositoryFragmentsContributor} contributing fragments based on the repository.
27+
* <p>
28+
* Implementations must define a no-args constructor.
29+
*
30+
* @author Mark Paluch
31+
* @since 5.0
32+
* @see QuerydslMongoPredicateExecutor
33+
*/
34+
public interface MongoRepositoryFragmentsContributor extends RepositoryFragmentsContributor {
35+
36+
MongoRepositoryFragmentsContributor DEFAULT = QuerydslContributor.INSTANCE;
37+
38+
/**
39+
* Returns a composed {@code MongoRepositoryFragmentsContributor} that first applies this contributor to its inputs,
40+
* and then applies the {@code after} contributor concatenating effectively both results. If evaluation of either
41+
* contributors throws an exception, it is relayed to the caller of the composed contributor.
42+
*
43+
* @param after the contributor to apply after this contributor is applied.
44+
* @return a composed contributor that first applies this contributor and then applies the {@code after} contributor.
45+
*/
46+
default MongoRepositoryFragmentsContributor andThen(MongoRepositoryFragmentsContributor after) {
47+
48+
Assert.notNull(after, "MongoRepositoryFragmentsContributor must not be null");
49+
50+
return new MongoRepositoryFragmentsContributor() {
51+
52+
@Override
53+
public RepositoryComposition.RepositoryFragments contribute(RepositoryMetadata metadata,
54+
MongoEntityInformation<?, ?> entityInformation, MongoOperations operations) {
55+
return MongoRepositoryFragmentsContributor.this.contribute(metadata, entityInformation, operations)
56+
.append(after.contribute(metadata, entityInformation, operations));
57+
}
58+
59+
@Override
60+
public RepositoryComposition.RepositoryFragments describe(RepositoryMetadata metadata) {
61+
return MongoRepositoryFragmentsContributor.this.describe(metadata).append(after.describe(metadata));
62+
}
63+
};
64+
}
65+
66+
/**
67+
* Creates {@link RepositoryComposition.RepositoryFragments} based on {@link RepositoryMetadata} to add
68+
* MongoDB-specific extensions.
69+
*
70+
* @param metadata repository metadata.
71+
* @param entityInformation must not be {@literal null}.
72+
* @param operations must not be {@literal null}.
73+
* @return {@link RepositoryComposition.RepositoryFragments} to be added to the repository.
74+
*/
75+
RepositoryComposition.RepositoryFragments contribute(RepositoryMetadata metadata,
76+
MongoEntityInformation<?, ?> entityInformation, MongoOperations operations);
77+
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.repository.support;
17+
18+
import static org.springframework.data.querydsl.QuerydslUtils.*;
19+
20+
import org.springframework.data.mongodb.core.MongoOperations;
21+
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
22+
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
23+
import org.springframework.data.repository.core.RepositoryMetadata;
24+
import org.springframework.data.repository.core.support.RepositoryComposition;
25+
import org.springframework.data.repository.core.support.RepositoryFragment;
26+
import org.springframework.data.repository.core.support.RepositoryFragmentsContributor;
27+
28+
/**
29+
* MongoDB-specific {@link RepositoryFragmentsContributor} contributing Querydsl fragments if a repository implements
30+
* {@link QuerydslPredicateExecutor}.
31+
*
32+
* @author Mark Paluch
33+
* @since 5.0
34+
* @see QuerydslMongoPredicateExecutor
35+
*/
36+
enum QuerydslContributor implements MongoRepositoryFragmentsContributor {
37+
38+
INSTANCE;
39+
40+
@Override
41+
public RepositoryComposition.RepositoryFragments contribute(RepositoryMetadata metadata,
42+
MongoEntityInformation<?, ?> entityInformation, MongoOperations operations) {
43+
44+
if (isQuerydslRepository(metadata)) {
45+
46+
QuerydslMongoPredicateExecutor<?> executor = new QuerydslMongoPredicateExecutor<>(entityInformation, operations);
47+
48+
return RepositoryComposition.RepositoryFragments
49+
.of(RepositoryFragment.implemented(QuerydslPredicateExecutor.class, executor));
50+
}
51+
52+
return RepositoryComposition.RepositoryFragments.empty();
53+
}
54+
55+
@Override
56+
public RepositoryComposition.RepositoryFragments describe(RepositoryMetadata metadata) {
57+
58+
if (isQuerydslRepository(metadata)) {
59+
return RepositoryComposition.RepositoryFragments
60+
.of(RepositoryFragment.structural(QuerydslPredicateExecutor.class, QuerydslMongoPredicateExecutor.class));
61+
}
62+
63+
return RepositoryComposition.RepositoryFragments.empty();
64+
}
65+
66+
private static boolean isQuerydslRepository(RepositoryMetadata metadata) {
67+
return QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(metadata.getRepositoryInterface());
68+
}
69+
70+
}

0 commit comments

Comments
 (0)