Skip to content

Commit 65aa371

Browse files
committed
Fix NPE on IndexQuery with source and version.
Original Pull Request #1894 Closes #1893 (cherry picked from commit 36b449c) (cherry picked from commit c0781ef)
1 parent b3da178 commit 65aa371

File tree

2 files changed

+65
-33
lines changed

2 files changed

+65
-33
lines changed

src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
114114
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
115115
import org.springframework.data.elasticsearch.core.query.*;
116+
import org.springframework.data.mapping.context.MappingContext;
116117
import org.springframework.lang.Nullable;
117118
import org.springframework.util.Assert;
118119
import org.springframework.util.StringUtils;
@@ -891,15 +892,17 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
891892
String indexName = index.getIndexName();
892893
IndexRequest indexRequest;
893894

894-
if (query.getObject() != null) {
895-
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId();
895+
Object queryObject = query.getObject();
896+
897+
if (queryObject != null) {
898+
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(queryObject) : query.getId();
896899
// If we have a query id and a document id, do not ask ES to generate one.
897900
if (id != null) {
898901
indexRequest = new IndexRequest(indexName).id(id);
899902
} else {
900903
indexRequest = new IndexRequest(indexName);
901904
}
902-
indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE);
905+
indexRequest.source(elasticsearchConverter.mapObject(queryObject).toJson(), Requests.INDEX_CONTENT_TYPE);
903906
} else if (query.getSource() != null) {
904907
indexRequest = new IndexRequest(indexName).id(query.getId()).source(query.getSource(),
905908
Requests.INDEX_CONTENT_TYPE);
@@ -910,7 +913,8 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
910913

911914
if (query.getVersion() != null) {
912915
indexRequest.version(query.getVersion());
913-
VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass());
916+
VersionType versionType = retrieveVersionTypeFromPersistentEntity(
917+
queryObject != null ? queryObject.getClass() : null);
914918
indexRequest.versionType(versionType);
915919
}
916920

@@ -935,15 +939,16 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query,
935939

936940
IndexRequestBuilder indexRequestBuilder;
937941

938-
if (query.getObject() != null) {
939-
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId();
942+
Object queryObject = query.getObject();
943+
if (queryObject != null) {
944+
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(queryObject) : query.getId();
940945
// If we have a query id and a document id, do not ask ES to generate one.
941946
if (id != null) {
942947
indexRequestBuilder = client.prepareIndex(indexName, type, id);
943948
} else {
944949
indexRequestBuilder = client.prepareIndex(indexName, type);
945950
}
946-
indexRequestBuilder.setSource(elasticsearchConverter.mapObject(query.getObject()).toJson(),
951+
indexRequestBuilder.setSource(elasticsearchConverter.mapObject(queryObject).toJson(),
947952
Requests.INDEX_CONTENT_TYPE);
948953
} else if (query.getSource() != null) {
949954
indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource(),
@@ -954,7 +959,8 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query,
954959
}
955960
if (query.getVersion() != null) {
956961
indexRequestBuilder.setVersion(query.getVersion());
957-
VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass());
962+
VersionType versionType = retrieveVersionTypeFromPersistentEntity(
963+
queryObject != null ? queryObject.getClass() : null);
958964
indexRequestBuilder.setVersionType(versionType);
959965
}
960966

@@ -1577,10 +1583,19 @@ private String getPersistentEntityId(Object entity) {
15771583
return null;
15781584
}
15791585

1580-
private VersionType retrieveVersionTypeFromPersistentEntity(Class<?> clazz) {
1586+
private VersionType retrieveVersionTypeFromPersistentEntity(@Nullable Class<?> clazz) {
1587+
1588+
MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext = elasticsearchConverter
1589+
.getMappingContext();
1590+
1591+
ElasticsearchPersistentEntity<?> persistentEntity = clazz != null ? mappingContext.getPersistentEntity(clazz)
1592+
: null;
15811593

1582-
VersionType versionType = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz)
1583-
.getVersionType();
1594+
VersionType versionType = null;
1595+
1596+
if (persistentEntity != null) {
1597+
versionType = persistentEntity.getVersionType();
1598+
}
15841599

15851600
return versionType != null ? versionType : VersionType.EXTERNAL;
15861601
}
@@ -1606,25 +1621,25 @@ private boolean hasSeqNoPrimaryTermProperty(@Nullable Class<?> entityClass) {
16061621
return entity.hasSeqNoPrimaryTermProperty();
16071622
}
16081623

1609-
private FetchSourceContext getFetchSourceContext(Query searchQuery) {
1610-
FetchSourceContext fetchSourceContext = null;
1611-
SourceFilter sourceFilter = searchQuery.getSourceFilter();
1612-
1613-
if (!isEmpty(searchQuery.getFields())) {
1614-
if (sourceFilter == null) {
1615-
sourceFilter = new FetchSourceFilter(toArray(searchQuery.getFields()), null);
1616-
} else {
1617-
ArrayList<String> arrayList = new ArrayList<>();
1618-
Collections.addAll(arrayList, sourceFilter.getIncludes());
1619-
sourceFilter = new FetchSourceFilter(toArray(arrayList), null);
1620-
}
1621-
1622-
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1623-
} else if (sourceFilter != null) {
1624-
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1625-
}
1626-
return fetchSourceContext;
1627-
}
1624+
private FetchSourceContext getFetchSourceContext(Query searchQuery) {
1625+
FetchSourceContext fetchSourceContext = null;
1626+
SourceFilter sourceFilter = searchQuery.getSourceFilter();
1627+
1628+
if (!isEmpty(searchQuery.getFields())) {
1629+
if (sourceFilter == null) {
1630+
sourceFilter = new FetchSourceFilter(toArray(searchQuery.getFields()), null);
1631+
} else {
1632+
ArrayList<String> arrayList = new ArrayList<>();
1633+
Collections.addAll(arrayList, sourceFilter.getIncludes());
1634+
sourceFilter = new FetchSourceFilter(toArray(arrayList), null);
1635+
}
1636+
1637+
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1638+
} else if (sourceFilter != null) {
1639+
fetchSourceContext = new FetchSourceContext(true, sourceFilter.getIncludes(), sourceFilter.getExcludes());
1640+
}
1641+
return fetchSourceContext;
1642+
}
16281643

16291644
// endregion
16301645

src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,8 @@ void shouldUsePageableOnMoreLikeThisQueries() {
11081108
Collection<String> ids = IntStream.rangeClosed(1, 10).mapToObj(i -> nextIdAsString()).collect(Collectors.toList());
11091109
ids.add(referenceId);
11101110
ids.stream()
1111-
.map(id -> getIndexQuery(SampleEntity.builder().id(id).message(sampleMessage).version(System.currentTimeMillis()).build()))
1111+
.map(id -> getIndexQuery(
1112+
SampleEntity.builder().id(id).message(sampleMessage).version(System.currentTimeMillis()).build()))
11121113
.forEach(indexQuery -> operations.index(indexQuery, index));
11131114
indexOperations.refresh();
11141115

@@ -1123,7 +1124,8 @@ void shouldUsePageableOnMoreLikeThisQueries() {
11231124
assertThat(searchHits.getTotalHits()).isEqualTo(10);
11241125
assertThat(searchHits.getSearchHits()).hasSize(5);
11251126

1126-
Collection<String> returnedIds = searchHits.getSearchHits().stream().map(SearchHit::getId).collect(Collectors.toList());
1127+
Collection<String> returnedIds = searchHits.getSearchHits().stream().map(SearchHit::getId)
1128+
.collect(Collectors.toList());
11271129

11281130
moreLikeThisQuery.setPageable(PageRequest.of(1, 5));
11291131

@@ -3669,6 +3671,21 @@ void shouldTrackTotalHitsIsOff() {
36693671
softly.assertThat(searchHits.getTotalHitsRelation()).isEqualTo(TotalHitsRelation.OFF);
36703672
softly.assertAll();
36713673
}
3674+
@Test // #1893
3675+
@DisplayName("should index document from source with version")
3676+
void shouldIndexDocumentFromSourceWithVersion() {
3677+
3678+
String source = "{\n" + //
3679+
" \"answer\": 42\n" + //
3680+
"}";
3681+
IndexQuery query = new IndexQueryBuilder() //
3682+
.withId("42") //
3683+
.withSource(source) //
3684+
.withVersion(42L) //
3685+
.build();
3686+
3687+
operations.index(query, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY));
3688+
}
36723689

36733690
@Data
36743691
@NoArgsConstructor
@@ -3865,5 +3882,5 @@ static class SampleJoinEntity {
38653882
@JoinTypeRelation(parent = "question", children = { "answer" }) }) private JoinField<String> myJoinField;
38663883
@Field(type = Text) private String text;
38673884
}
3868-
//endregion
3885+
// endregion
38693886
}

0 commit comments

Comments
 (0)