diff --git a/pom.xml b/pom.xml index 0e19b3788..4be105416 100644 --- a/pom.xml +++ b/pom.xml @@ -452,7 +452,7 @@ integration-test - org.springframework.data.elasticsearch.core.geo.* + org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter* toString diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java index fa84ec8dc..f64335842 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java @@ -77,6 +77,14 @@ public @interface Document { */ Dynamic dynamic() default Dynamic.INHERIT; + /** + * Specifies if the id property should also be stored in the Elasticsearch document source. Default value is + * {@literal true} + * + * @since 5.1 + */ + boolean storeIdInSource() default true; + /** * @since 4.3 */ 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 0562dd180..e1513b454 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 @@ -939,7 +939,13 @@ public class MappingElasticsearchConverter for (ElasticsearchPersistentProperty property : entity) { - if (!property.isWritable() || property.isIndexedIndexNameProperty()) { + if (!property.isWritable() // + || property.isIndexedIndexNameProperty() // + || (property.isIdProperty() && !entity.storeIdInSource())) { + continue; + } + + if (property.isIdProperty() && !entity.storeIdInSource()) { continue; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 86ec740eb..ae21d3a35 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -175,4 +175,10 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends BasicPersistentEntit private final ConcurrentHashMap indexNameExpressions = new ConcurrentHashMap<>(); private final Lazy indexNameEvaluationContext = Lazy.of(this::getIndexNameEvaluationContext); + private final boolean storeIdInSource; + public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation, ContextConfiguration contextConfiguration) { @@ -106,8 +107,10 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit this.versionType = document.versionType(); this.createIndexAndMapping = document.createIndex(); this.dynamic = document.dynamic(); + this.storeIdInSource = document.storeIdInSource(); } else { this.dynamic = Dynamic.INHERIT; + this.storeIdInSource = true; } Routing routingAnnotation = AnnotatedElementUtils.findMergedAnnotation(clazz, Routing.class); @@ -192,6 +195,11 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit return writeTypeHints; } + @Override + public boolean storeIdInSource() { + return storeIdInSource; + } + @Override public void addPersistentProperty(ElasticsearchPersistentProperty property) { super.addPersistentProperty(property); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 85798809a..43599f0db 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -1871,6 +1871,28 @@ public class MappingElasticsearchConverterUnitTests { return sink; } + @Test // #2364 + @DisplayName("should not write id property to document source if configured so") + void shouldNotWriteIdPropertyToDocumentSourceIfConfiguredSo() throws JSONException { + + @Language("JSON") + var expected = """ + { + "_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$DontWriteIdToSourceEntity", + "text": "some text" + } + """; + var entity = new DontWriteIdToSourceEntity(); + entity.setId("42"); + entity.setText("some text"); + + Document document = Document.create(); + mappingElasticsearchConverter.write(entity, document); + String json = document.toJson(); + + assertEquals(expected, json, true); + } + // region entities public static class Sample { @Nullable public @ReadOnlyProperty String readOnly; @@ -2885,7 +2907,7 @@ public class MappingElasticsearchConverterUnitTests { @Nullable private Set childrenSet; public ImmutableEntityWithCollections(@Nullable List stringList, @Nullable Set stringSet, - @Nullable List childrenList, @Nullable Set childrenSet) { + @Nullable List childrenList, @Nullable Set childrenSet) { this.stringList = stringList; this.stringSet = stringSet; this.childrenList = childrenList; @@ -2927,6 +2949,31 @@ public class MappingElasticsearchConverterUnitTests { } } } + + @org.springframework.data.elasticsearch.annotations.Document(indexName = "doesnt-matter", storeIdInSource = false) + static class DontWriteIdToSourceEntity { + @Nullable private String id; + @Nullable + @Field(type = FieldType.Text) private String text; + + @Nullable + public String getId() { + return id; + } + + public void setId(@Nullable String id) { + this.id = id; + } + + @Nullable + public String getText() { + return text; + } + + public void setText(@Nullable String text) { + this.text = text; + } + } // endregion private static String reverse(Object o) {