diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 55a5d37fe..ef49b14db 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -113,6 +113,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersiste import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.mapping.context.MappingContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -891,15 +892,17 @@ class RequestFactory { String indexName = index.getIndexName(); IndexRequest indexRequest; - if (query.getObject() != null) { - String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); + Object queryObject = query.getObject(); + + if (queryObject != null) { + String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(queryObject) : query.getId(); // If we have a query id and a document id, do not ask ES to generate one. if (id != null) { indexRequest = new IndexRequest(indexName).id(id); } else { indexRequest = new IndexRequest(indexName); } - indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE); + indexRequest.source(elasticsearchConverter.mapObject(queryObject).toJson(), Requests.INDEX_CONTENT_TYPE); } else if (query.getSource() != null) { indexRequest = new IndexRequest(indexName).id(query.getId()).source(query.getSource(), Requests.INDEX_CONTENT_TYPE); @@ -910,7 +913,8 @@ class RequestFactory { if (query.getVersion() != null) { indexRequest.version(query.getVersion()); - VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); + VersionType versionType = retrieveVersionTypeFromPersistentEntity( + queryObject != null ? queryObject.getClass() : null); indexRequest.versionType(versionType); } @@ -935,15 +939,16 @@ class RequestFactory { IndexRequestBuilder indexRequestBuilder; - if (query.getObject() != null) { - String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); + Object queryObject = query.getObject(); + if (queryObject != null) { + String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(queryObject) : query.getId(); // If we have a query id and a document id, do not ask ES to generate one. if (id != null) { indexRequestBuilder = client.prepareIndex(indexName, type, id); } else { indexRequestBuilder = client.prepareIndex(indexName, type); } - indexRequestBuilder.setSource(elasticsearchConverter.mapObject(query.getObject()).toJson(), + indexRequestBuilder.setSource(elasticsearchConverter.mapObject(queryObject).toJson(), Requests.INDEX_CONTENT_TYPE); } else if (query.getSource() != null) { indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource(), @@ -954,7 +959,8 @@ class RequestFactory { } if (query.getVersion() != null) { indexRequestBuilder.setVersion(query.getVersion()); - VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); + VersionType versionType = retrieveVersionTypeFromPersistentEntity( + queryObject != null ? queryObject.getClass() : null); indexRequestBuilder.setVersionType(versionType); } @@ -1577,10 +1583,19 @@ class RequestFactory { return null; } - private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { + private VersionType retrieveVersionTypeFromPersistentEntity(@Nullable Class clazz) { - VersionType versionType = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz) - .getVersionType(); + MappingContext, ElasticsearchPersistentProperty> mappingContext = elasticsearchConverter + .getMappingContext(); + + ElasticsearchPersistentEntity persistentEntity = clazz != null ? mappingContext.getPersistentEntity(clazz) + : null; + + VersionType versionType = null; + + if (persistentEntity != null) { + versionType = persistentEntity.getVersionType(); + } return versionType != null ? versionType : VersionType.EXTERNAL; } @@ -1606,25 +1621,25 @@ class RequestFactory { return entity.hasSeqNoPrimaryTermProperty(); } - private FetchSourceContext getFetchSourceContext(Query searchQuery) { - FetchSourceContext fetchSourceContext = null; - SourceFilter sourceFilter = searchQuery.getSourceFilter(); + private FetchSourceContext getFetchSourceContext(Query searchQuery) { + FetchSourceContext fetchSourceContext = null; + SourceFilter sourceFilter = searchQuery.getSourceFilter(); - if (!isEmpty(searchQuery.getFields())) { - if (sourceFilter == null) { - sourceFilter = new FetchSourceFilter(toArray(searchQuery.getFields()), null); - } else { - ArrayList arrayList = new ArrayList<>(); - Collections.addAll(arrayList, sourceFilter.getIncludes()); - sourceFilter = new FetchSourceFilter(toArray(arrayList), null); - } + if (!isEmpty(searchQuery.getFields())) { + if (sourceFilter == null) { + sourceFilter = new FetchSourceFilter(toArray(searchQuery.getFields()), null); + } else { + ArrayList arrayList = new ArrayList<>(); + Collections.addAll(arrayList, sourceFilter.getIncludes()); + sourceFilter = new FetchSourceFilter(toArray(arrayList), null); + } - fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } else if (sourceFilter != null) { - fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - return fetchSourceContext; - } + fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes()); + } else if (sourceFilter != null) { + fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes()); + } + return fetchSourceContext; + } // endregion diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index b485b4d47..8de3a1d3c 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -1108,7 +1108,8 @@ public abstract class ElasticsearchTemplateTests { Collection ids = IntStream.rangeClosed(1, 10).mapToObj(i -> nextIdAsString()).collect(Collectors.toList()); ids.add(referenceId); ids.stream() - .map(id -> getIndexQuery(SampleEntity.builder().id(id).message(sampleMessage).version(System.currentTimeMillis()).build())) + .map(id -> getIndexQuery( + SampleEntity.builder().id(id).message(sampleMessage).version(System.currentTimeMillis()).build())) .forEach(indexQuery -> operations.index(indexQuery, index)); indexOperations.refresh(); @@ -1123,7 +1124,8 @@ public abstract class ElasticsearchTemplateTests { assertThat(searchHits.getTotalHits()).isEqualTo(10); assertThat(searchHits.getSearchHits()).hasSize(5); - Collection returnedIds = searchHits.getSearchHits().stream().map(SearchHit::getId).collect(Collectors.toList()); + Collection returnedIds = searchHits.getSearchHits().stream().map(SearchHit::getId) + .collect(Collectors.toList()); moreLikeThisQuery.setPageable(PageRequest.of(1, 5)); @@ -3669,6 +3671,21 @@ public abstract class ElasticsearchTemplateTests { softly.assertThat(searchHits.getTotalHitsRelation()).isEqualTo(TotalHitsRelation.OFF); softly.assertAll(); } + @Test // #1893 + @DisplayName("should index document from source with version") + void shouldIndexDocumentFromSourceWithVersion() { + + String source = "{\n" + // + " \"answer\": 42\n" + // + "}"; + IndexQuery query = new IndexQueryBuilder() // + .withId("42") // + .withSource(source) // + .withVersion(42L) // + .build(); + + operations.index(query, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + } @Data @NoArgsConstructor @@ -3865,5 +3882,5 @@ public abstract class ElasticsearchTemplateTests { @JoinTypeRelation(parent = "question", children = { "answer" }) }) private JoinField myJoinField; @Field(type = Text) private String text; } - //endregion + // endregion }