Skip to content

Commit c688045

Browse files
committed
Fix IndexOutOfBoundsException when try to map inner hits with no results returned.
Original Pull Request #1998 Closes #1997 (cherry picked from commit 2aba7a5)
1 parent 873a6de commit c688045

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
import java.util.stream.Collectors;
2424

2525
import org.elasticsearch.search.aggregations.Aggregations;
26-
import org.slf4j.Logger;
27-
import org.slf4j.LoggerFactory;
26+
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
2827
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
2928
import org.springframework.data.elasticsearch.core.document.Document;
3029
import org.springframework.data.elasticsearch.core.document.NestedMetaData;
@@ -43,12 +42,11 @@
4342
* @author Peter-Josef Meisch
4443
* @author Mark Paluch
4544
* @author Roman Puchkovskiy
45+
* @author Sascha Woo
4646
* @since 4.0
4747
*/
4848
class SearchHitMapping<T> {
4949

50-
private static final Logger LOGGER = LoggerFactory.getLogger(SearchHitMapping.class);
51-
5250
private final Class<T> type;
5351
private final ElasticsearchConverter converter;
5452
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
@@ -169,7 +167,7 @@ private Map<String, SearchHits<?>> mapInnerHits(SearchDocument searchDocument) {
169167
*/
170168
private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, Class<T> type) {
171169

172-
if (searchHits.getTotalHits() == 0) {
170+
if (searchHits.isEmpty()) {
173171
return searchHits;
174172
}
175173

@@ -210,7 +208,7 @@ private SearchHits<?> mapInnerDocuments(SearchHits<SearchDocument> searchHits, C
210208
searchHits.getAggregations());
211209
}
212210
} catch (Exception e) {
213-
LOGGER.warn("Could not map inner_hits", e);
211+
throw new UncategorizedElasticsearchException("Unable to convert inner hits.", e);
214212
}
215213

216214
return searchHits;

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

+44
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
import org.elasticsearch.action.update.UpdateRequest;
5454
import org.elasticsearch.cluster.metadata.AliasMetadata;
5555
import org.elasticsearch.index.VersionType;
56+
import org.elasticsearch.index.query.InnerHitBuilder;
57+
import org.elasticsearch.index.query.QueryBuilders;
58+
import org.elasticsearch.join.query.HasChildQueryBuilder;
59+
import org.elasticsearch.join.query.JoinQueryBuilders;
5660
import org.elasticsearch.join.query.ParentIdQueryBuilder;
5761
import org.elasticsearch.script.Script;
5862
import org.elasticsearch.script.ScriptType;
@@ -2988,6 +2992,46 @@ public void shouldAddAliasWithGivenRoutingValue() {
29882992
indexOperations.removeAlias(aliasQuery);
29892993
}
29902994

2995+
@Test // #1997
2996+
@DisplayName("should return document with inner hits size zero")
2997+
void shouldReturnDocumentWithInnerHitsSizeZero() {
2998+
2999+
// given
3000+
SampleJoinEntity sampleQuestionEntity1 = new SampleJoinEntity();
3001+
sampleQuestionEntity1.setUuid("q1");
3002+
sampleQuestionEntity1.setText("This is a question");
3003+
sampleQuestionEntity1.setMyJoinField(new JoinField<>("question"));
3004+
3005+
SampleJoinEntity sampleAnswerEntity1 = new SampleJoinEntity();
3006+
sampleAnswerEntity1.setUuid("a1");
3007+
sampleAnswerEntity1.setText("This is an answer");
3008+
sampleAnswerEntity1.setMyJoinField(new JoinField<>("answer", sampleQuestionEntity1.getUuid()));
3009+
3010+
SampleJoinEntity sampleAnswerEntity2 = new SampleJoinEntity();
3011+
sampleAnswerEntity1.setUuid("a2");
3012+
sampleAnswerEntity1.setText("This is an answer");
3013+
sampleAnswerEntity1.setMyJoinField(new JoinField<>("answer", sampleQuestionEntity1.getUuid()));
3014+
3015+
IndexOperations indexOps = operations.indexOps(SampleJoinEntity.class);
3016+
operations.save(Arrays.asList(sampleQuestionEntity1, sampleAnswerEntity1, sampleAnswerEntity2));
3017+
indexOps.refresh();
3018+
3019+
// when
3020+
Query query = new NativeSearchQueryBuilder().withQuery(
3021+
JoinQueryBuilders.hasChildQuery("answer", matchAllQuery(), org.apache.lucene.search.join.ScoreMode.Avg)
3022+
.innerHit(new InnerHitBuilder("innerHits").setSize(0)))
3023+
.build();
3024+
3025+
SearchHits<SampleJoinEntity> searchHits = operations.search(query, SampleJoinEntity.class);
3026+
3027+
// then
3028+
assertThat(searchHits).isNotNull();
3029+
assertThat(searchHits.getTotalHits()).isEqualTo(1);
3030+
assertThat(searchHits.getSearchHits()).hasSize(1);
3031+
assertThat(searchHits.getSearchHit(0).getInnerHits().size()).isEqualTo(1);
3032+
assertThat(searchHits.getSearchHit(0).getInnerHits("innerHits").getTotalHits()).isEqualTo(1);
3033+
}
3034+
29913035
@Test // DATAES-541
29923036
public void shouldRemoveAlias() {
29933037

0 commit comments

Comments
 (0)