Fix IndexOutOfBoundsException when try to map inner hits with no results returned.

Original Pull Request #1998
Closes #1997
Co-authored-by: Peter-Josef Meisch <pj.meisch@sothawo.com>

(cherry picked from commit 49324a369af627e390f981ed6b793f0f503526c7)
This commit is contained in:
Sascha Woo 2021-11-23 20:08:50 +01:00 committed by Peter-Josef Meisch
parent 3256a2bfe0
commit 4f3aa52958
No known key found for this signature in database
GPG Key ID: DE108246970C7708
2 changed files with 31 additions and 2 deletions

View File

@ -24,6 +24,7 @@ import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
@ -45,6 +46,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @author Roman Puchkovskiy
* @author Matt Gilene
* @author Sascha Woo
* @since 4.0
*/
class SearchHitMapping<T> {
@ -194,7 +196,7 @@ class SearchHitMapping<T> {
*/
private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, Class<T> type) {
if (searchHits.getTotalHits() == 0) {
if (searchHits.isEmpty()) {
return searchHits;
}
@ -239,7 +241,7 @@ class SearchHitMapping<T> {
searchHits.getSuggest());
}
} catch (Exception e) {
LOGGER.warn("Could not map inner_hits", e);
throw new UncategorizedElasticsearchException("Unable to convert inner hits.", e);
}
return searchHits;

View File

@ -2783,6 +2783,33 @@ public abstract class ElasticsearchTemplateTests {
assertThat(searchHits.getSearchHit(1).getInnerHits("innerHits").getTotalHits()).isEqualTo(1);
}
@Test // #1997
@DisplayName("should return document with inner hits size zero")
void shouldReturnDocumentWithInnerHitsSizeZero() {
// given
SampleEntity sampleEntity = SampleEntity.builder().id(nextIdAsString()).message("message 1").rate(1)
.version(System.currentTimeMillis()).build();
List<IndexQuery> indexQueries = getIndexQueries(Arrays.asList(sampleEntity));
operations.bulkIndex(indexQueries, IndexCoordinates.of(indexNameProvider.indexName()));
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withCollapseBuilder(new CollapseBuilder("rate").setInnerHits(new InnerHitBuilder("innerHits").setSize(0)))
.build();
// when
SearchHits<SampleEntity> searchHits = operations.search(searchQuery, SampleEntity.class,
IndexCoordinates.of(indexNameProvider.indexName()));
// then
assertThat(searchHits).isNotNull();
assertThat(searchHits.getTotalHits()).isEqualTo(1);
assertThat(searchHits.getSearchHits()).hasSize(1);
assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo("message 1");
}
private IndexQuery getIndexQuery(SampleEntity sampleEntity) {
return new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity)
.withVersion(sampleEntity.getVersion()).build();