From bd38e8fe485b1d6860dabb1873cef4c6cab968f3 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 18 Oct 2020 18:33:08 +0200 Subject: [PATCH] DATAES-956 - Prevent double converter registration. --- .../MappingElasticsearchConverter.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index a98d6a05a2..b0aaa17d00 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -82,7 +82,8 @@ public class MappingElasticsearchConverter private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final GenericConversionService conversionService; - private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); + // don't access directly, use getConversions(). to prevent null access + @Nullable private CustomConversions conversions = null; private final EntityInstantiators instantiators = new EntityInstantiators(); private final ElasticsearchTypeMapper typeMapper; @@ -133,6 +134,14 @@ public void setConversions(CustomConversions conversions) { this.conversions = conversions; } + private CustomConversions getConversions() { + + if (conversions == null) { + conversions = new ElasticsearchCustomConversions(Collections.emptyList()); + } + return conversions; + } + /* * (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() @@ -140,7 +149,7 @@ public void setConversions(CustomConversions conversions) { @Override public void afterPropertiesSet() { DateFormatterRegistrar.addDateConverters(conversionService); - conversions.registerConvertersIn(conversionService); + getConversions().registerConvertersIn(conversionService); } // region read @@ -151,7 +160,7 @@ public R read(Class type, Document source) { TypeInformation typeHint = ClassTypeInformation.from((Class) ClassUtils.getUserClass(type)); typeHint = (TypeInformation) typeMapper.readType(source, typeHint); - if (conversions.hasCustomReadTarget(Map.class, typeHint.getType())) { + if (getConversions().hasCustomReadTarget(Map.class, typeHint.getType())) { R converted = conversionService.convert(source, typeHint.getType()); if (converted == null) { // EntityReader.read is defined as non nullable , so we cannot return null @@ -177,7 +186,7 @@ protected R readEntity(ElasticsearchPersistentEntity entity, Map(targetEntity, propertyValueProvider, null)); @@ -223,6 +232,7 @@ protected R readEntity(ElasticsearchPersistentEntity entity, Map R readValue(@Nullable Object source, ElasticsearchPersistentProper if (property.hasPropertyConverter()) { source = propertyConverterRead(property, source); } else if (TemporalAccessor.class.isAssignableFrom(property.getType()) - && !conversions.hasCustomReadTarget(source.getClass(), rawType)) { + && !getConversions().hasCustomReadTarget(source.getClass(), rawType)) { // log at most 5 times String propertyName = property.getOwner().getType().getSimpleName() + '.' + property.getName(); @@ -291,7 +301,7 @@ protected R readValue(@Nullable Object source, ElasticsearchPersistentProper } } - if (conversions.hasCustomReadTarget(source.getClass(), rawType)) { + if (getConversions().hasCustomReadTarget(source.getClass(), rawType)) { return rawType.cast(conversionService.convert(source, rawType)); } else if (source instanceof List) { return readCollectionValue((List) source, property, targetType); @@ -356,8 +366,6 @@ && isSimpleType(componentType.getType())) { } else if (value instanceof Map) { target .add(readMapValue((Map) value, property, property.getTypeInformation().getActualType())); - } else { - target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value)); } } } @@ -423,7 +431,7 @@ private Object readSimpleValue(@Nullable Object value, TypeInformation target return value; } - if (conversions.hasCustomReadTarget(value.getClass(), target)) { + if (getConversions().hasCustomReadTarget(value.getClass(), target)) { return conversionService.convert(value, target); } @@ -477,7 +485,7 @@ public void write(Object source, Document sink) { typeMapper.writeType(source.getClass(), sink); } - Optional> customTarget = conversions.getCustomWriteTarget(entityType, Map.class); + Optional> customTarget = getConversions().getCustomWriteTarget(entityType, Map.class); if (customTarget.isPresent()) { sink.putAll(conversionService.convert(source, Map.class)); @@ -526,7 +534,7 @@ protected void writeProperties(ElasticsearchPersistentEntity entity, Persiste if (property.hasPropertyConverter()) { value = propertyConverterWrite(property, value); } else if (TemporalAccessor.class.isAssignableFrom(property.getActualType()) - && !conversions.hasCustomWriteTarget(value.getClass())) { + && !getConversions().hasCustomWriteTarget(value.getClass())) { // log at most 5 times String propertyName = entity.getType().getSimpleName() + '.' + property.getName(); @@ -568,7 +576,7 @@ private Object propertyConverterWrite(ElasticsearchPersistentProperty property, protected void writeProperty(ElasticsearchPersistentProperty property, Object value, MapValueAccessor sink) { - Optional> customWriteTarget = conversions.getCustomWriteTarget(value.getClass()); + Optional> customWriteTarget = getConversions().getCustomWriteTarget(value.getClass()); if (customWriteTarget.isPresent()) { Class writeTarget = customWriteTarget.get(); @@ -595,7 +603,7 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va @Nullable protected Object getWriteSimpleValue(Object value) { - Optional> customTarget = conversions.getCustomWriteTarget(value.getClass()); + Optional> customTarget = getConversions().getCustomWriteTarget(value.getClass()); if (customTarget.isPresent()) { return conversionService.convert(value, customTarget.get()); @@ -759,8 +767,8 @@ private boolean requiresTypeHint(TypeInformation type, Class actualType, } } - return !conversions.isSimpleType(type.getType()) && !type.isCollectionLike() - && !conversions.hasCustomWriteTarget(type.getType()); + return !getConversions().isSimpleType(type.getType()) && !type.isCollectionLike() + && !getConversions().hasCustomWriteTarget(type.getType()); } /** @@ -789,7 +797,7 @@ private boolean isSimpleType(Object value) { } private boolean isSimpleType(Class type) { - return conversions.isSimpleType(type); + return getConversions().isSimpleType(type); } // endregion @@ -819,7 +827,7 @@ private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity field.setName(property.getFieldName()); if (property.hasPropertyConverter()) { - ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); + ElasticsearchPersistentPropertyConverter propertyConverter = Objects.requireNonNull(property.getPropertyConverter()); criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> { Object value = criteriaEntry.getValue(); if (value.getClass().isArray()) {