Skip to content

Commit 000c467

Browse files
committed
Defer MappingContext access inPersistentEntities.
We now fetch mapping contexts from Iterable<MappingContext> later, when accessing PersistentEntities API to defer potential resolution when e.g. obtaining beans from a BeanFactory. Closes #3310
1 parent fd5292c commit 000c467

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

src/main/java/org/springframework/data/mapping/context/PersistentEntities.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.data.mapping.MappingException;
3131
import org.springframework.data.mapping.PersistentEntity;
3232
import org.springframework.data.mapping.PersistentProperty;
33+
import org.springframework.data.util.Lazy;
3334
import org.springframework.data.util.Streamable;
3435
import org.springframework.data.util.TypeInformation;
3536
import org.springframework.lang.Nullable;
@@ -46,7 +47,7 @@
4647
*/
4748
public class PersistentEntities implements Streamable<PersistentEntity<?, ? extends PersistentProperty<?>>> {
4849

49-
private final Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>> contexts;
50+
private final Lazy<Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>>> contexts;
5051

5152
/**
5253
* Creates a new {@link PersistentEntities} for the given {@link MappingContext}s.
@@ -58,9 +59,9 @@ public PersistentEntities(Iterable<? extends MappingContext<?, ?>> contexts) {
5859

5960
Assert.notNull(contexts, "MappingContexts must not be null");
6061

61-
this.contexts = contexts instanceof Collection
62+
this.contexts = Lazy.of(() -> contexts instanceof Collection
6263
? (Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>>) contexts
63-
: StreamSupport.stream(contexts.spliterator(), false).collect(Collectors.toList());
64+
: StreamSupport.stream(contexts.spliterator(), false).toList());
6465
}
6566

6667
/**
@@ -88,7 +89,7 @@ public static PersistentEntities of(MappingContext<?, ?>... contexts) {
8889
*/
8990
public Optional<PersistentEntity<?, ? extends PersistentProperty<?>>> getPersistentEntity(Class<?> type) {
9091

91-
for (MappingContext<?, ? extends PersistentProperty<?>> context : contexts) {
92+
for (MappingContext<?, ? extends PersistentProperty<?>> context : getMappingContexts()) {
9293
if (context.hasPersistentEntityFor(type)) {
9394
return Optional.of(context.getRequiredPersistentEntity(type));
9495
}
@@ -112,14 +113,16 @@ public static PersistentEntities of(MappingContext<?, ?>... contexts) {
112113

113114
Assert.notNull(type, "Domain type must not be null");
114115

115-
if (contexts.size() == 1) {
116-
return contexts.iterator().next().getRequiredPersistentEntity(type);
116+
Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>> mappingContexts = getMappingContexts();
117+
118+
if (mappingContexts.size() == 1) {
119+
return mappingContexts.iterator().next().getRequiredPersistentEntity(type);
117120
}
118121

119122
return getPersistentEntity(type).orElseThrow(() -> {
120123
return new MappingException(String.format(
121124
"Cannot get or create PersistentEntity for type %s; PersistentEntities knows about %s MappingContext instances and therefore cannot identify a single responsible one; Please configure the initialEntitySet through an entity scan using the base package in your configuration to pre initialize contexts",
122-
type.getName(), contexts.size()));
125+
type.getName(), mappingContexts.size()));
123126
});
124127
}
125128

@@ -138,14 +141,16 @@ public <T> Optional<T> mapOnContext(Class<?> type,
138141
Assert.notNull(type, "Type must not be null");
139142
Assert.notNull(combiner, "Combining BiFunction must not be null");
140143

141-
if (contexts.size() == 1) {
142-
return contexts.stream() //
144+
Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>> mappingContexts = getMappingContexts();
145+
146+
if (mappingContexts.size() == 1) {
147+
return mappingContexts.stream() //
143148
.filter(it -> it.getPersistentEntity(type) != null) //
144149
.map(it -> combiner.apply(it, it.getRequiredPersistentEntity(type))) //
145150
.findFirst();
146151
}
147152

148-
return contexts.stream() //
153+
return mappingContexts.stream() //
149154
.filter(it -> it.hasPersistentEntityFor(type)) //
150155
.map(it -> combiner.apply(it, it.getRequiredPersistentEntity(type))) //
151156
.findFirst();
@@ -160,7 +165,7 @@ public Streamable<TypeInformation<?>> getManagedTypes() {
160165

161166
Set<TypeInformation<?>> target = new HashSet<>();
162167

163-
for (MappingContext<?, ? extends PersistentProperty<?>> context : contexts) {
168+
for (MappingContext<?, ? extends PersistentProperty<?>> context : getMappingContexts()) {
164169
target.addAll(context.getManagedTypes());
165170
}
166171

@@ -172,7 +177,7 @@ public Streamable<TypeInformation<?>> getManagedTypes() {
172177

173178
List<PersistentEntity<?, ? extends PersistentProperty<?>>> target = new ArrayList<>();
174179

175-
for (MappingContext<?, ? extends PersistentProperty<?>> context : contexts) {
180+
for (MappingContext<?, ? extends PersistentProperty<?>> context : getMappingContexts()) {
176181
target.addAll(context.getPersistentEntities());
177182
}
178183

@@ -236,7 +241,7 @@ public TypeInformation<?> getTypeUltimatelyReferredToBy(PersistentProperty<?> pr
236241
private PersistentEntity<?, ?> getEntityIdentifiedBy(TypeInformation<?> type) {
237242

238243
Collection<PersistentEntity<?, ?>> entities = new ArrayList<>();
239-
for (MappingContext<?, ? extends PersistentProperty<?>> context : contexts) {
244+
for (MappingContext<?, ? extends PersistentProperty<?>> context : getMappingContexts()) {
240245

241246
for (PersistentEntity<?, ? extends PersistentProperty<?>> persistentProperties : context
242247
.getPersistentEntities()) {
@@ -261,4 +266,9 @@ public TypeInformation<?> getTypeUltimatelyReferredToBy(PersistentProperty<?> pr
261266

262267
return entities.isEmpty() ? null : entities.iterator().next();
263268
}
269+
270+
private Collection<? extends MappingContext<?, ? extends PersistentProperty<?>>> getMappingContexts() {
271+
return this.contexts.get();
272+
}
273+
264274
}

src/test/java/org/springframework/data/mapping/context/PersistentEntitiesUnitTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
*
3636
* @author Oliver Gierke
3737
* @author Christoph Strobl
38-
* @author Mar Paluch
38+
* @author Mark Paluch
3939
*/
4040
@ExtendWith(MockitoExtension.class)
4141
class PersistentEntitiesUnitTests {
@@ -48,6 +48,16 @@ void rejectsNullMappingContexts() {
4848
assertThatIllegalArgumentException().isThrownBy(() -> new PersistentEntities(null));
4949
}
5050

51+
@Test // GH-3310
52+
@SuppressWarnings({ "unchecked", "rawtypes" })
53+
void lazilyAccessesIterableOfMappingContext() {
54+
55+
Iterable iterable = mock(Iterable.class);
56+
new PersistentEntities(iterable);
57+
58+
verifyNoInteractions(iterable);
59+
}
60+
5161
@Test // DATACMNS-458
5262
void returnsPersistentEntitiesFromMappingContexts() {
5363

0 commit comments

Comments
 (0)