diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java index 2e0ec4bb2..60a941da8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java @@ -67,14 +67,17 @@ public DefaultElasticsearchTypeMapper(@Nullable String typeKey, TypeAliasAccesso this.typeKey = typeKey; } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.convert.MongoTypeMapper#isTypeKey(java.lang.String) - */ + @Override public boolean isTypeKey(String key) { return typeKey != null && typeKey.equals(key); } + @Override + @Nullable + public String getTypeKey() { + return typeKey; + } + /* * (non-Javadoc) * @see org.springframework.data.convert.DefaultTypeMapper#getFallbackTypeFor(java.lang.Object) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java index 9c68ecc87..5ba3fb580 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java @@ -21,6 +21,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.mapping.context.MappingContext; +import org.springframework.lang.Nullable; /** * Elasticsearch specific {@link TypeMapper} definition. @@ -39,6 +40,13 @@ public interface ElasticsearchTypeMapper extends TypeMapper> */ boolean isTypeKey(String key); + /** + * @return the type key. + * @since 4.4 + */ + @Nullable + String getTypeKey(); + default boolean containsTypeInformation(Map source) { return readType(source) != null; } 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 7d534820a..b26583f02 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 @@ -92,6 +92,7 @@ public class MappingElasticsearchConverter private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); private final SpELContext spELContext = new SpELContext(new MapAccessor()); private final EntityInstantiators instantiators = new EntityInstantiators(); + private final ElasticsearchTypeMapper typeMapper; public MappingElasticsearchConverter( MappingContext, ElasticsearchPersistentProperty> mappingContext) { @@ -106,6 +107,7 @@ public MappingElasticsearchConverter( this.mappingContext = mappingContext; this.conversionService = conversionService != null ? conversionService : new DefaultConversionService(); + this.typeMapper = ElasticsearchTypeMapper.create(mappingContext); } @Override @@ -145,12 +147,16 @@ public void afterPropertiesSet() { conversions.registerConvertersIn(conversionService); } + public ElasticsearchTypeMapper getTypeMapper() { + return typeMapper; + } + // region read/write @Override public R read(Class type, Document source) { - Reader reader = new Reader(mappingContext, conversionService, conversions, spELContext, instantiators); + Reader reader = new Reader(mappingContext, conversionService, conversions, typeMapper, spELContext, instantiators); return reader.read(type, source); } @@ -159,7 +165,7 @@ public void write(Object source, Document sink) { Assert.notNull(source, "source to map must not be null"); - Writer writer = new Writer(mappingContext, conversionService, conversions); + Writer writer = new Writer(mappingContext, conversionService, conversions, typeMapper); writer.write(source, sink); } @@ -176,11 +182,11 @@ private static class Base { private Base( MappingContext, ElasticsearchPersistentProperty> mappingContext, - GenericConversionService conversionService, CustomConversions conversions) { + GenericConversionService conversionService, CustomConversions conversions, ElasticsearchTypeMapper typeMapper) { this.mappingContext = mappingContext; this.conversionService = conversionService; this.conversions = conversions; - this.typeMapper = ElasticsearchTypeMapper.create(mappingContext); + this.typeMapper = typeMapper; } } @@ -195,10 +201,10 @@ private static class Reader extends Base { public Reader( MappingContext, ElasticsearchPersistentProperty> mappingContext, - GenericConversionService conversionService, CustomConversions conversions, SpELContext spELContext, - EntityInstantiators instantiators) { + GenericConversionService conversionService, CustomConversions conversions, ElasticsearchTypeMapper typeMapper, + SpELContext spELContext, EntityInstantiators instantiators) { - super(mappingContext, conversionService, conversions); + super(mappingContext, conversionService, conversions, typeMapper); this.spELContext = spELContext; this.instantiators = instantiators; } @@ -670,8 +676,8 @@ static private class Writer extends Base { public Writer( MappingContext, ElasticsearchPersistentProperty> mappingContext, - GenericConversionService conversionService, CustomConversions conversions) { - super(mappingContext, conversionService, conversions); + GenericConversionService conversionService, CustomConversions conversions, ElasticsearchTypeMapper typeMapper) { + super(mappingContext, conversionService, conversions, typeMapper); } void write(Object source, Document sink) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 847f61160..6d1138dd7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -35,6 +35,8 @@ import org.springframework.data.elasticsearch.backend.elasticsearch7.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchTypeMapper; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; @@ -88,7 +90,7 @@ public class MappingBuilder { private static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length"; private static final String COMPLETION_CONTEXTS = "contexts"; - private static final String TYPEHINT_PROPERTY = "_class"; + private static final String TYPEHINT_PROPERTY = ElasticsearchTypeMapper.DEFAULT_TYPE_KEY; private static final String TYPE_DYNAMIC = "dynamic"; private static final String TYPE_VALUE_KEYWORD = "keyword"; @@ -189,7 +191,17 @@ protected String buildPropertyMapping(ElasticsearchPersistentEntity entity, private void writeTypeHintMapping(ObjectNode propertiesNode) throws IOException { if (writeTypeHints) { - propertiesNode.set(TYPEHINT_PROPERTY, objectMapper.createObjectNode() // + String typeHintProperty = null; + + if (elasticsearchConverter instanceof MappingElasticsearchConverter) { + typeHintProperty = ((MappingElasticsearchConverter) elasticsearchConverter).getTypeMapper().getTypeKey(); + } + + if (typeHintProperty == null) { + typeHintProperty = TYPEHINT_PROPERTY; + } + + propertiesNode.set(typeHintProperty, objectMapper.createObjectNode() // .put(FIELD_PARAM_TYPE, TYPE_VALUE_KEYWORD) // .put(FIELD_PARAM_INDEX, false) // .put(FIELD_PARAM_DOC_VALUES, false));