Skip to content

Commit 7198a02

Browse files
authored
DATAES-956 - Prevent double converter registration.
Original PR: #541
1 parent 8a6e125 commit 7198a02

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public class MappingElasticsearchConverter
8282
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
8383
private final GenericConversionService conversionService;
8484

85-
private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList());
85+
// don't access directly, use getConversions(). to prevent null access
86+
@Nullable private CustomConversions conversions = null;
8687
private final EntityInstantiators instantiators = new EntityInstantiators();
8788

8889
private final ElasticsearchTypeMapper typeMapper;
@@ -133,14 +134,22 @@ public void setConversions(CustomConversions conversions) {
133134
this.conversions = conversions;
134135
}
135136

137+
private CustomConversions getConversions() {
138+
139+
if (conversions == null) {
140+
conversions = new ElasticsearchCustomConversions(Collections.emptyList());
141+
}
142+
return conversions;
143+
}
144+
136145
/*
137146
* (non-Javadoc)
138147
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
139148
*/
140149
@Override
141150
public void afterPropertiesSet() {
142151
DateFormatterRegistrar.addDateConverters(conversionService);
143-
conversions.registerConvertersIn(conversionService);
152+
getConversions().registerConvertersIn(conversionService);
144153
}
145154

146155
// region read
@@ -151,7 +160,7 @@ public <R> R read(Class<R> type, Document source) {
151160
TypeInformation<R> typeHint = ClassTypeInformation.from((Class<R>) ClassUtils.getUserClass(type));
152161
typeHint = (TypeInformation<R>) typeMapper.readType(source, typeHint);
153162

154-
if (conversions.hasCustomReadTarget(Map.class, typeHint.getType())) {
163+
if (getConversions().hasCustomReadTarget(Map.class, typeHint.getType())) {
155164
R converted = conversionService.convert(source, typeHint.getType());
156165
if (converted == null) {
157166
// EntityReader.read is defined as non nullable , so we cannot return null
@@ -177,7 +186,7 @@ protected <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String,
177186

178187
EntityInstantiator instantiator = instantiators.getInstantiatorFor(targetEntity);
179188

180-
@SuppressWarnings("unchecked")
189+
@SuppressWarnings({"unchecked", "ConstantConditions"})
181190
R instance = (R) instantiator.createInstance(targetEntity,
182191
new PersistentEntityParameterValueProvider<>(targetEntity, propertyValueProvider, null));
183192

@@ -223,6 +232,7 @@ protected <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String,
223232
if (source instanceof SearchDocument) {
224233
SearchDocument searchDocument = (SearchDocument) source;
225234
if (targetEntity.hasScoreProperty()) {
235+
//noinspection ConstantConditions
226236
targetEntity.getPropertyAccessor(result) //
227237
.setProperty(targetEntity.getScoreProperty(), searchDocument.getScore());
228238
}
@@ -276,7 +286,7 @@ protected <R> R readValue(@Nullable Object source, ElasticsearchPersistentProper
276286
if (property.hasPropertyConverter()) {
277287
source = propertyConverterRead(property, source);
278288
} else if (TemporalAccessor.class.isAssignableFrom(property.getType())
279-
&& !conversions.hasCustomReadTarget(source.getClass(), rawType)) {
289+
&& !getConversions().hasCustomReadTarget(source.getClass(), rawType)) {
280290

281291
// log at most 5 times
282292
String propertyName = property.getOwner().getType().getSimpleName() + '.' + property.getName();
@@ -291,7 +301,7 @@ protected <R> R readValue(@Nullable Object source, ElasticsearchPersistentProper
291301
}
292302
}
293303

294-
if (conversions.hasCustomReadTarget(source.getClass(), rawType)) {
304+
if (getConversions().hasCustomReadTarget(source.getClass(), rawType)) {
295305
return rawType.cast(conversionService.convert(source, rawType));
296306
} else if (source instanceof List) {
297307
return readCollectionValue((List<?>) source, property, targetType);
@@ -356,8 +366,6 @@ && isSimpleType(componentType.getType())) {
356366
} else if (value instanceof Map) {
357367
target
358368
.add(readMapValue((Map<String, Object>) value, property, property.getTypeInformation().getActualType()));
359-
} else {
360-
target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map<String, Object>) value));
361369
}
362370
}
363371
}
@@ -423,7 +431,7 @@ private Object readSimpleValue(@Nullable Object value, TypeInformation<?> target
423431
return value;
424432
}
425433

426-
if (conversions.hasCustomReadTarget(value.getClass(), target)) {
434+
if (getConversions().hasCustomReadTarget(value.getClass(), target)) {
427435
return conversionService.convert(value, target);
428436
}
429437

@@ -477,7 +485,7 @@ public void write(Object source, Document sink) {
477485
typeMapper.writeType(source.getClass(), sink);
478486
}
479487

480-
Optional<Class<?>> customTarget = conversions.getCustomWriteTarget(entityType, Map.class);
488+
Optional<Class<?>> customTarget = getConversions().getCustomWriteTarget(entityType, Map.class);
481489

482490
if (customTarget.isPresent()) {
483491
sink.putAll(conversionService.convert(source, Map.class));
@@ -526,7 +534,7 @@ protected void writeProperties(ElasticsearchPersistentEntity<?> entity, Persiste
526534
if (property.hasPropertyConverter()) {
527535
value = propertyConverterWrite(property, value);
528536
} else if (TemporalAccessor.class.isAssignableFrom(property.getActualType())
529-
&& !conversions.hasCustomWriteTarget(value.getClass())) {
537+
&& !getConversions().hasCustomWriteTarget(value.getClass())) {
530538

531539
// log at most 5 times
532540
String propertyName = entity.getType().getSimpleName() + '.' + property.getName();
@@ -568,7 +576,7 @@ private Object propertyConverterWrite(ElasticsearchPersistentProperty property,
568576

569577
protected void writeProperty(ElasticsearchPersistentProperty property, Object value, MapValueAccessor sink) {
570578

571-
Optional<Class<?>> customWriteTarget = conversions.getCustomWriteTarget(value.getClass());
579+
Optional<Class<?>> customWriteTarget = getConversions().getCustomWriteTarget(value.getClass());
572580

573581
if (customWriteTarget.isPresent()) {
574582
Class<?> writeTarget = customWriteTarget.get();
@@ -595,7 +603,7 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va
595603

596604
@Nullable
597605
protected Object getWriteSimpleValue(Object value) {
598-
Optional<Class<?>> customTarget = conversions.getCustomWriteTarget(value.getClass());
606+
Optional<Class<?>> customTarget = getConversions().getCustomWriteTarget(value.getClass());
599607

600608
if (customTarget.isPresent()) {
601609
return conversionService.convert(value, customTarget.get());
@@ -759,8 +767,8 @@ private boolean requiresTypeHint(TypeInformation<?> type, Class<?> actualType,
759767
}
760768
}
761769

762-
return !conversions.isSimpleType(type.getType()) && !type.isCollectionLike()
763-
&& !conversions.hasCustomWriteTarget(type.getType());
770+
return !getConversions().isSimpleType(type.getType()) && !type.isCollectionLike()
771+
&& !getConversions().hasCustomWriteTarget(type.getType());
764772
}
765773

766774
/**
@@ -789,7 +797,7 @@ private boolean isSimpleType(Object value) {
789797
}
790798

791799
private boolean isSimpleType(Class<?> type) {
792-
return conversions.isSimpleType(type);
800+
return getConversions().isSimpleType(type);
793801
}
794802
// endregion
795803

@@ -819,7 +827,7 @@ private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity<?>
819827
field.setName(property.getFieldName());
820828

821829
if (property.hasPropertyConverter()) {
822-
ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter();
830+
ElasticsearchPersistentPropertyConverter propertyConverter = Objects.requireNonNull(property.getPropertyConverter());
823831
criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> {
824832
Object value = criteriaEntry.getValue();
825833
if (value.getClass().isArray()) {

0 commit comments

Comments
 (0)