Skip to content

Commit 259c43a

Browse files
authored
Fix handling of array-of-strings parameters for @Query-annotated queries.
Original Pull Request #2182 Closes #2135
1 parent a2802ce commit 259c43a

File tree

4 files changed

+102
-98
lines changed

4 files changed

+102
-98
lines changed

src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) {
8282

8383
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor);
8484

85-
Query query = createQuery(
86-
new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor));
85+
Query query = createQuery(parameterAccessor);
8786

8887
if (queryMethod.hasAnnotatedHighlight()) {
8988
query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery());

src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java

-95
This file was deleted.

src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java

+45-1
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,37 @@ void shouldUseConverterOnParameters() throws Exception {
144144
.isEqualTo("{ 'bool' : { 'must' : { 'term' : { 'car' : 'Toyota-Prius' } } } }");
145145
}
146146

147+
@Test // #2135
148+
@DisplayName("should handle array-of-strings parameters correctly")
149+
void shouldHandleArrayOfStringsParametersCorrectly() throws Exception {
150+
151+
List<String> otherNames = List.of("Wesley", "Emmett");
152+
153+
org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByOtherNames", otherNames);
154+
155+
assertThat(query).isInstanceOf(StringQuery.class);
156+
assertThat(((StringQuery) query).getSource())
157+
.isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : [\"Wesley\",\"Emmett\"] } } } }");
158+
}
159+
160+
@Test // #2135
161+
@DisplayName("should handle array-of-Integers parameters correctly")
162+
void shouldHandleArrayOfIntegerParametersCorrectly() throws Exception {
163+
164+
List<Integer> ages = List.of(42, 57);
165+
166+
org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByAges", ages);
167+
168+
assertThat(query).isInstanceOf(StringQuery.class);
169+
assertThat(((StringQuery) query).getSource())
170+
.isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'ages' : [42,57] } } } }");
171+
}
172+
147173
private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, Object... args)
148174
throws NoSuchMethodException {
149175

150-
Class<?>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
176+
Class<?>[] argTypes = Arrays.stream(args).map(Object::getClass)
177+
.map(clazz -> Collection.class.isAssignableFrom(clazz) ? List.class : clazz).toArray(Class[]::new);
151178
ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes);
152179
ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
153180

@@ -195,6 +222,12 @@ Person findWithRepeatedPlaceholder(String arg0, String arg1, String arg2, String
195222
@Query("{ 'bool' : { 'must' : { 'term' : { 'car' : '?0' } } } }")
196223
Mono<Person> findByCar(Car car);
197224

225+
@Query("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : ?0 } } } }")
226+
Flux<Person> findByOtherNames(List<String> otherNames);
227+
228+
@Query("{ 'bool' : { 'must' : { 'terms' : { 'ages' : ?0 } } } }")
229+
Flux<Person> findByAges(List<Integer> ages);
230+
198231
}
199232

200233
/**
@@ -211,6 +244,8 @@ public class Person {
211244

212245
@Nullable private String name;
213246

247+
@Nullable private List<String> otherNames;
248+
214249
@Nullable
215250
@Field(type = FieldType.Nested) private List<Car> car;
216251

@@ -235,6 +270,15 @@ public void setName(String name) {
235270
this.name = name;
236271
}
237272

273+
@Nullable
274+
public List<String> getOtherNames() {
275+
return otherNames;
276+
}
277+
278+
public void setOtherNames(List<String> otherNames) {
279+
this.otherNames = otherNames;
280+
}
281+
238282
@Nullable
239283
public List<Car> getCar() {
240284
return car;

src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryIntegrationTests.java

+56
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,52 @@ void derivedDeleteMethodShouldBeExecutedCorrectly() {
588588
assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue();
589589
}
590590

591+
@Test // #2135
592+
void FluxOfSearchHitForArrayQuery() {
593+
bulkIndex(new SampleEntity("id-one", "message1"), //
594+
new SampleEntity("id-two", "message2"), //
595+
new SampleEntity("id-three", "message3")) //
596+
.block();
597+
598+
repository.findAllViaAnnotatedQueryByMessageIn(List.of("message1", "message3")) //
599+
.as(StepVerifier::create) //
600+
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) //
601+
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
602+
.verifyComplete();
603+
604+
}
605+
606+
@Test // #2135
607+
void FluxOfSearchHitForIntegerArrayQuery() {
608+
bulkIndex(new SampleEntity("id-one", "test", 3), //
609+
new SampleEntity("id-two", "test test", 1), //
610+
new SampleEntity("id-three", "test test", 2)) //
611+
.block();
612+
613+
repository.findAllViaAnnotatedQueryByRatesIn(List.of(2, 3)) //
614+
.as(StepVerifier::create) //
615+
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) //
616+
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
617+
.verifyComplete();
618+
619+
}
620+
621+
@Test // #2135
622+
void FluxOfSearchHitForStringAndIntegerArrayQuery() {
623+
bulkIndex(new SampleEntity("id-one", "message1", 1), //
624+
new SampleEntity("id-two", "message2", 2), //
625+
new SampleEntity("id-three", "message3", 3), //
626+
new SampleEntity("id-four", "message4", 4), //
627+
new SampleEntity("id-five", "message5", 5)) //
628+
.block();
629+
630+
repository.findAllViaAnnotatedQueryByMessageInAndRatesIn(List.of("message5", "message3"), List.of(2, 3)) //
631+
.as(StepVerifier::create) //
632+
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
633+
.verifyComplete();
634+
635+
}
636+
591637
Mono<Void> bulkIndex(SampleEntity... entities) {
592638
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(indexNameProvider.indexName())).then();
593639
}
@@ -627,6 +673,16 @@ interface ReactiveSampleEntityRepository extends ReactiveCrudRepository<SampleEn
627673

628674
@CountQuery(value = "{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}")
629675
Mono<Long> retrieveCountByText(String message);
676+
677+
@Query("{ \"terms\": { \"message\": ?0 } }")
678+
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageIn(List<String> messages);
679+
680+
@Query("{ \"terms\": { \"rate\": ?0 } }")
681+
Flux<SampleEntity> findAllViaAnnotatedQueryByRatesIn(List<Integer> rates);
682+
683+
@Query("{\"bool\": {\"must\": [{ \"terms\": { \"message\": ?0 } }, { \"terms\": { \"rate\": ?1 } }] } }")
684+
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageInAndRatesIn(List<String> messages, List<Integer> rates);
685+
630686
}
631687

632688
@Document(indexName = "#{@indexNameProvider.indexName()}")

0 commit comments

Comments
 (0)