Skip to content

Commit 73d52cd

Browse files
committed
DynamicMapping annotation should be applicable to any object field.
Original Pull Request #1779 Closes #1767
1 parent 532bb85 commit 73d52cd

File tree

3 files changed

+76
-19
lines changed

3 files changed

+76
-19
lines changed

Diff for: src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java

+16-5
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
216216
Field fieldAnnotation = property.findAnnotation(Field.class);
217217
boolean isCompletionProperty = property.isCompletionProperty();
218218
boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property);
219+
DynamicMapping dynamicMapping = property.findAnnotation(DynamicMapping.class);
219220

220221
if (!isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) {
221222

@@ -230,7 +231,7 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
230231
: null;
231232

232233
mapEntity(builder, persistentEntity, false, property.getFieldName(), true, fieldAnnotation.type(),
233-
fieldAnnotation, property.findAnnotation(DynamicMapping.class));
234+
fieldAnnotation, dynamicMapping);
234235
return;
235236
}
236237
}
@@ -245,9 +246,9 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
245246
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
246247
applyDefaultIdFieldMapping(builder, property);
247248
} else if (multiField != null) {
248-
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty);
249+
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty, dynamicMapping);
249250
} else if (fieldAnnotation != null) {
250-
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty);
251+
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
251252
}
252253
}
253254

@@ -328,7 +329,7 @@ private void applyDefaultIdFieldMapping(XContentBuilder builder, ElasticsearchPe
328329
* @throws IOException
329330
*/
330331
private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
331-
Field annotation, boolean nestedOrObjectField) throws IOException {
332+
Field annotation, boolean nestedOrObjectField, @Nullable DynamicMapping dynamicMapping) throws IOException {
332333

333334
// build the property json, if empty skip it as this is no valid mapping
334335
XContentBuilder propertyBuilder = jsonBuilder().startObject();
@@ -340,6 +341,11 @@ private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersist
340341
}
341342

342343
builder.startObject(property.getFieldName());
344+
345+
if (nestedOrObjectField && dynamicMapping != null) {
346+
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
347+
}
348+
343349
addFieldMappingParameters(builder, annotation, nestedOrObjectField);
344350
builder.endObject();
345351
}
@@ -380,10 +386,15 @@ private void addJoinFieldMapping(XContentBuilder builder, ElasticsearchPersisten
380386
* @throws IOException
381387
*/
382388
private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
383-
MultiField annotation, boolean nestedOrObjectField) throws IOException {
389+
MultiField annotation, boolean nestedOrObjectField, @Nullable DynamicMapping dynamicMapping) throws IOException {
384390

385391
// main field
386392
builder.startObject(property.getFieldName());
393+
394+
if (nestedOrObjectField && dynamicMapping != null) {
395+
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
396+
}
397+
387398
addFieldMappingParameters(builder, annotation.mainField(), nestedOrObjectField);
388399

389400
// inner fields

Diff for: src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java

+38-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2020 the original author or authors.
2+
* Copyright 2013-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
import lombok.Setter;
3131

3232
import java.lang.Integer;
33+
import java.lang.Object;
3334
import java.math.BigDecimal;
3435
import java.util.Collection;
3536
import java.util.Collections;
@@ -263,11 +264,21 @@ void shouldWriteCorrectTermVectorValues() {
263264
/**
264265
* @author Xiao Yu
265266
*/
266-
@Setter
267-
@Getter
268-
@NoArgsConstructor
269-
@AllArgsConstructor
270-
@Builder
267+
@Test // #1767
268+
@DisplayName("should write dynamic mapping entries")
269+
void shouldWriteDynamicMappingEntries() {
270+
271+
IndexOperations indexOps = operations.indexOps(DynamicMappingEntity.class);
272+
indexOps.create();
273+
indexOps.putMapping();
274+
indexOps.delete();
275+
}
276+
277+
@Setter
278+
@Getter
279+
@NoArgsConstructor
280+
@AllArgsConstructor
281+
@Builder
271282
@Document(indexName = "ignore-above-index")
272283
static class IgnoreAboveEntity {
273284

@@ -647,4 +658,25 @@ static class TermVectorFieldEntity {
647658
@Field(type = FieldType.Text,
648659
termVector = TermVector.with_positions_offsets_payloads) private String with_positions_offsets_payloads;
649660
}
661+
662+
@Document(indexName = "dynamic-mapping")
663+
@DynamicMapping(DynamicMappingValue.False)
664+
static class DynamicMappingEntity {
665+
666+
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author;
667+
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
668+
type = FieldType.Object) private Map<String, Object> objectMap;
669+
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
670+
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
671+
672+
@Nullable
673+
public Author getAuthor() {
674+
return author;
675+
}
676+
677+
public void setAuthor(Author author) {
678+
this.author = author;
679+
}
680+
}
681+
650682
}

Diff for: src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderUnitTests.java

+22-8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.Date;
3838
import java.util.HashMap;
3939
import java.util.HashSet;
40+
import java.util.List;
4041
import java.util.Map;
4142
import java.util.Set;
4243

@@ -410,19 +411,28 @@ public void shouldSetFieldMappingProperties() throws JSONException {
410411
assertEquals(expected, mapping, true);
411412
}
412413

413-
@Test
414+
@Test // DATAES-148, #1767
414415
void shouldWriteDynamicMappingSettings() throws JSONException {
415416

416417
String expected = "{\n" + //
417-
" \"dynamic\": \"false\",\n" + //
418-
" \"properties\": {\n" + //
419-
" \"author\": {\n" + //
420-
" \"dynamic\": \"strict\",\n" + //
421-
" \"type\": \"object\",\n" + //
422-
" \"properties\": {}\n" + //
418+
" \"dynamic\": \"false\",\n" + //
419+
" \"properties\": {\n" + //
420+
" \"author\": {\n" + //
421+
" \"type\": \"object\",\n" + //
422+
" \"dynamic\": \"strict\",\n" + //
423+
" \"properties\": {\n" + //
423424
" }\n" + //
425+
" },\n" + //
426+
" \"objectMap\": {\n" + //
427+
" \"type\": \"object\",\n" + //
428+
" \"dynamic\": \"false\"\n" + //
429+
" },\n" + //
430+
" \"nestedObjectMap\": {\n" + //
431+
" \"type\": \"nested\",\n" + //
432+
" \"dynamic\": \"false\"\n" + //
424433
" }\n" + //
425-
"}\n";
434+
" }\n" + //
435+
"}"; //
426436

427437
String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class);
428438

@@ -898,6 +908,10 @@ static class FieldMappingParameters {
898908
static class ConfigureDynamicMappingEntity {
899909

900910
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author;
911+
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
912+
type = FieldType.Object) private Map<String, Object> objectMap;
913+
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
914+
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
901915

902916
@Nullable
903917
public Author getAuthor() {

0 commit comments

Comments
 (0)