Fix handling of array-of-strings parameters for @Query-annotated queries.

Original Pull Request  #2182
Closes #2135

(cherry picked from commit 259c43af19db269476d31bfe5df5554807b7b2f9)
(cherry picked from commit aa4aecacdf0596578577461af5129cf12c9a5c7b)
This commit is contained in:
diamondT 2022-06-27 21:35:06 +03:00 committed by Peter-Josef Meisch
parent c58e3b3a8f
commit 474ff84d6e
4 changed files with 227 additions and 169 deletions

View File

@ -82,8 +82,7 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor); ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor);
Query query = createQuery( Query query = createQuery(parameterAccessor);
new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor));
if (queryMethod.hasAnnotatedHighlight()) { if (queryMethod.hasAnnotatedHighlight()) {
query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery()); query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery());

View File

@ -1,95 +0,0 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.repository.query;
import java.util.Iterator;
import java.util.Optional;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.lang.Nullable;
/**
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 3.2
*/
public class ConvertingParameterAccessor implements ElasticsearchParameterAccessor {
private final ElasticsearchConverter converter;
private final ElasticsearchParameterAccessor delegate;
public ConvertingParameterAccessor(ElasticsearchConverter converter, ElasticsearchParameterAccessor delegate) {
this.converter = converter;
this.delegate = delegate;
}
@Override
public Object[] getValues() {
return delegate.getValues();
}
@Override
public Pageable getPageable() {
return delegate.getPageable();
}
@Override
public Sort getSort() {
return delegate.getSort();
}
@Override
public Optional<Class<?>> getDynamicProjection() {
return delegate.getDynamicProjection();
}
@Override
public Class<?> findDynamicProjection() {
return delegate.findDynamicProjection();
}
@Override
public Object getBindableValue(int index) {
return getConvertedValue(delegate.getBindableValue(index));
}
@Override
public boolean hasBindableNullValue() {
return delegate.hasBindableNullValue();
}
@Override
public Iterator<Object> iterator() {
return delegate.iterator();
}
@Nullable
private Object getConvertedValue(Object value) {
if (value == null) {
return "null";
}
if (converter.getConversionService().canConvert(value.getClass(), String.class)) {
return converter.getConversionService().convert(value, String.class);
}
return value.toString();
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2021 the original author or authors. * Copyright 2019-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -144,10 +144,37 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri
.isEqualTo("{ 'bool' : { 'must' : { 'term' : { 'car' : 'Toyota-Prius' } } } }"); .isEqualTo("{ 'bool' : { 'must' : { 'term' : { 'car' : 'Toyota-Prius' } } } }");
} }
@Test // #2135
@DisplayName("should handle array-of-strings parameters correctly")
void shouldHandleArrayOfStringsParametersCorrectly() throws Exception {
List<String> otherNames = Arrays.asList("Wesley", "Emmett");
org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByOtherNames", otherNames);
assertThat(query).isInstanceOf(StringQuery.class);
assertThat(((StringQuery) query).getSource())
.isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : [\"Wesley\",\"Emmett\"] } } } }");
}
@Test // #2135
@DisplayName("should handle array-of-Integers parameters correctly")
void shouldHandleArrayOfIntegerParametersCorrectly() throws Exception {
List<Integer> ages = Arrays.asList(42, 57);
org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByAges", ages);
assertThat(query).isInstanceOf(StringQuery.class);
assertThat(((StringQuery) query).getSource())
.isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'ages' : [42,57] } } } }");
}
private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, Object... args) private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, Object... args)
throws NoSuchMethodException { throws NoSuchMethodException {
Class<?>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new); Class<?>[] argTypes = Arrays.stream(args).map(Object::getClass)
.map(clazz -> Collection.class.isAssignableFrom(clazz) ? List.class : clazz).toArray(Class[]::new);
ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes); ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes);
ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod); ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
@ -195,6 +222,12 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri
@Query("{ 'bool' : { 'must' : { 'term' : { 'car' : '?0' } } } }") @Query("{ 'bool' : { 'must' : { 'term' : { 'car' : '?0' } } } }")
Mono<Person> findByCar(Car car); Mono<Person> findByCar(Car car);
@Query("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : ?0 } } } }")
Flux<Person> findByOtherNames(List<String> otherNames);
@Query("{ 'bool' : { 'must' : { 'terms' : { 'ages' : ?0 } } } }")
Flux<Person> findByAges(List<Integer> ages);
} }
/** /**
@ -206,10 +239,13 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri
@Document(indexName = "test-index-person-reactive-repository-string-query") @Document(indexName = "test-index-person-reactive-repository-string-query")
public class Person { public class Person {
@Nullable @Id private String id; @Nullable
@Id private String id;
@Nullable private String name; @Nullable private String name;
@Nullable private List<String> otherNames;
@Nullable @Field(type = FieldType.Nested) private List<Car> car; @Nullable @Field(type = FieldType.Nested) private List<Car> car;
@Nullable @Field(type = FieldType.Nested, includeInParent = true) private List<Book> books; @Nullable @Field(type = FieldType.Nested, includeInParent = true) private List<Book> books;
@ -232,6 +268,15 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri
this.name = name; this.name = name;
} }
@Nullable
public List<String> getOtherNames() {
return otherNames;
}
public void setOtherNames(List<String> otherNames) {
this.otherNames = otherNames;
}
@Nullable @Nullable
public List<Car> getCar() { public List<Car> getCar() {
return car; return car;

View File

@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import static org.springframework.data.elasticsearch.core.query.Query.*; import static org.springframework.data.elasticsearch.core.query.Query.*;
import org.springframework.data.elasticsearch.annotations.FieldType;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
@ -91,7 +92,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
operations.indexOps(IndexCoordinates.of(INDEX)).delete().block(); operations.indexOps(IndexCoordinates.of(INDEX)).delete().block();
} }
@Test // DATAES-519 @Test
// DATAES-519
void saveShouldSaveSingleEntity() { void saveShouldSaveSingleEntity() {
repository.save(new SampleEntity()) // repository.save(new SampleEntity()) //
@ -105,7 +107,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
return operations.exists(id, IndexCoordinates.of(INDEX)); return operations.exists(id, IndexCoordinates.of(INDEX));
} }
@Test // DATAES-519 @Test
// DATAES-519
void saveShouldComputeMultipleEntities() { void saveShouldComputeMultipleEntities() {
repository.saveAll(Arrays.asList(new SampleEntity(), new SampleEntity(), new SampleEntity())) repository.saveAll(Arrays.asList(new SampleEntity(), new SampleEntity(), new SampleEntity()))
@ -118,14 +121,16 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519, DATAES-767, DATAES-822 @Test
// DATAES-519, DATAES-767, DATAES-822
void findByIdShouldErrorIfIndexDoesNotExist() { void findByIdShouldErrorIfIndexDoesNotExist() {
repository.findById("id-two") // repository.findById("id-two") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectError(RestStatusException.class); .expectError(RestStatusException.class);
} }
@Test // DATAES-519 @Test
// DATAES-519
void findShouldRetrieveSingleEntityById() { void findShouldRetrieveSingleEntityById() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -138,7 +143,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void findByIdShouldCompleteIfNothingFound() { void findByIdShouldCompleteIfNothingFound() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -150,7 +156,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-720 @Test
// DATAES-720
void findAllShouldReturnAllElements() { void findAllShouldReturnAllElements() {
// make sure to be above the default page size of the Query interface // make sure to be above the default page size of the Query interface
int count = DEFAULT_PAGE_SIZE * 2; int count = DEFAULT_PAGE_SIZE * 2;
@ -165,12 +172,14 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() { void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() {
repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete(); repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void findAllByIdShouldRetrieveMatchingDocuments() { void findAllByIdShouldRetrieveMatchingDocuments() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -185,7 +194,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void findAllByIdShouldCompleteWhenNothingFound() { void findAllByIdShouldCompleteWhenNothingFound() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -198,7 +208,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-717 @Test
// DATAES-717
void shouldReturnFluxOfSearchHit() { void shouldReturnFluxOfSearchHit() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -213,7 +224,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-717 @Test
// DATAES-717
void shouldReturnFluxOfSearchHitForStringQuery() { void shouldReturnFluxOfSearchHitForStringQuery() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -228,7 +240,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-372 @Test
// DATAES-372
void shouldReturnHighlightsOnAnnotatedMethod() { void shouldReturnHighlightsOnAnnotatedMethod() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -246,7 +259,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-372 @Test
// DATAES-372
void shouldReturnHighlightsOnAnnotatedStringQueryMethod() { void shouldReturnHighlightsOnAnnotatedStringQueryMethod() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -264,14 +278,16 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519, DATAES-767, DATAES-822 @Test
// DATAES-519, DATAES-767, DATAES-822
void countShouldErrorWhenIndexDoesNotExist() { void countShouldErrorWhenIndexDoesNotExist() {
repository.count() // repository.count() //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectError(RestStatusException.class); .expectError(RestStatusException.class);
} }
@Test // DATAES-519 @Test
// DATAES-519
void countShouldCountDocuments() { void countShouldCountDocuments() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -281,7 +297,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete(); repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void existsByIdShouldReturnTrueIfExists() { void existsByIdShouldReturnTrueIfExists() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -295,7 +312,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void existsByIdShouldReturnFalseIfNotExists() { void existsByIdShouldReturnFalseIfNotExists() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -309,7 +327,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void countShouldCountMatchingDocuments() { void countShouldCountMatchingDocuments() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -336,7 +355,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void existsShouldReturnTrueIfExists() { void existsShouldReturnTrueIfExists() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -350,7 +370,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void existsShouldReturnFalseIfNotExists() { void existsShouldReturnFalseIfNotExists() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -364,7 +385,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void deleteByIdShouldCompleteIfNothingDeleted() { void deleteByIdShouldCompleteIfNothingDeleted() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -374,14 +396,16 @@ class SimpleReactiveElasticsearchRepositoryTests {
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
} }
@Test // DATAES-519, DATAES-767, DATAES-822, DATAES-678 @Test
// DATAES-519, DATAES-767, DATAES-822, DATAES-678
void deleteByIdShouldCompleteWhenIndexDoesNotExist() { void deleteByIdShouldCompleteWhenIndexDoesNotExist() {
repository.deleteById("does-not-exist") // repository.deleteById("does-not-exist") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void deleteByIdShouldDeleteEntry() { void deleteByIdShouldDeleteEntry() {
SampleEntity toBeDeleted = new SampleEntity("id-two"); SampleEntity toBeDeleted = new SampleEntity("id-two");
@ -393,19 +417,22 @@ class SimpleReactiveElasticsearchRepositoryTests {
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
} }
@Test // DATAES-976 @Test
// DATAES-976
void deleteAllByIdShouldDeleteEntry() { void deleteAllByIdShouldDeleteEntry() {
SampleEntity toBeDeleted = new SampleEntity("id-two"); SampleEntity toBeDeleted = new SampleEntity("id-two");
bulkIndex(new SampleEntity("id-one"), toBeDeleted) // bulkIndex(new SampleEntity("id-one"), toBeDeleted) //
.block(); .block();
repository.deleteAllById(Collections.singletonList(toBeDeleted.getId())).as(StepVerifier::create).verifyComplete(); repository.deleteAllById(Collections.singletonList(toBeDeleted.getId())).as(StepVerifier::create)
.verifyComplete();
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
} }
@Test // DATAES-519 @Test
// DATAES-519
void deleteShouldDeleteEntry() { void deleteShouldDeleteEntry() {
SampleEntity toBeDeleted = new SampleEntity("id-two"); SampleEntity toBeDeleted = new SampleEntity("id-two");
@ -417,7 +444,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
} }
@Test // DATAES-519 @Test
// DATAES-519
void deleteAllShouldDeleteGivenEntries() { void deleteAllShouldDeleteGivenEntries() {
SampleEntity toBeDeleted = new SampleEntity("id-one"); SampleEntity toBeDeleted = new SampleEntity("id-one");
@ -434,7 +462,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
assertThat(documentWithIdExistsInIndex(hangInThere.getId()).block()).isTrue(); assertThat(documentWithIdExistsInIndex(hangInThere.getId()).block()).isTrue();
} }
@Test // DATAES-519 @Test
// DATAES-519
void deleteAllShouldDeleteAllEntries() { void deleteAllShouldDeleteAllEntries() {
bulkIndex(new SampleEntity("id-one"), // bulkIndex(new SampleEntity("id-one"), //
@ -450,7 +479,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderMethodShouldBeExecutedCorrectly() { void derivedFinderMethodShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -464,7 +494,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() { void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -478,7 +509,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() { void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "test", 3), // bulkIndex(new SampleEntity("id-one", "test", 3), //
@ -494,7 +526,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() { void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "test", 3), // bulkIndex(new SampleEntity("id-one", "test", 3), //
@ -510,7 +543,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() { void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "test", 3), // bulkIndex(new SampleEntity("id-one", "test", 3), //
@ -525,7 +559,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() { void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -539,7 +574,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void annotatedFinderMethodShouldBeExecutedCorrectly() { void annotatedFinderMethodShouldBeExecutedCorrectly() {
int count = 30; int count = 30;
@ -555,7 +591,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // #1917 @Test
// #1917
void annotatedFinderMethodPagedShouldBeExecutedCorrectly() { void annotatedFinderMethodPagedShouldBeExecutedCorrectly() {
int count = 30; int count = 30;
@ -575,7 +612,8 @@ class SimpleReactiveElasticsearchRepositoryTests {
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-519 @Test
// DATAES-519
void derivedDeleteMethodShouldBeExecutedCorrectly() { void derivedDeleteMethodShouldBeExecutedCorrectly() {
bulkIndex(new SampleEntity("id-one", "message"), // bulkIndex(new SampleEntity("id-one", "message"), //
@ -593,6 +631,56 @@ class SimpleReactiveElasticsearchRepositoryTests {
assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue(); assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue();
} }
@Test
// #2135
void FluxOfSearchHitForArrayQuery() {
bulkIndex(new SampleEntity("id-one", "message1"), //
new SampleEntity("id-two", "message2"), //
new SampleEntity("id-three", "message3")) //
.block();
repository.findAllViaAnnotatedQueryByMessageIn(Arrays.asList("message1", "message3")) //
.as(StepVerifier::create) //
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) //
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
.verifyComplete();
}
@Test
// #2135
void FluxOfSearchHitForIntegerArrayQuery() {
bulkIndex(new SampleEntity("id-one", "test", 3), //
new SampleEntity("id-two", "test test", 1), //
new SampleEntity("id-three", "test test", 2)) //
.block();
repository.findAllViaAnnotatedQueryByRatesIn(Arrays.asList(2, 3)) //
.as(StepVerifier::create) //
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) //
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
.verifyComplete();
}
@Test
// #2135
void FluxOfSearchHitForStringAndIntegerArrayQuery() {
bulkIndex(new SampleEntity("id-one", "message1", 1), //
new SampleEntity("id-two", "message2", 2), //
new SampleEntity("id-three", "message3", 3), //
new SampleEntity("id-four", "message4", 4), //
new SampleEntity("id-five", "message5", 5)) //
.block();
repository.findAllViaAnnotatedQueryByMessageInAndRatesIn(Arrays.asList("message5", "message3"), Arrays.asList(2,
3)) //
.as(StepVerifier::create) //
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) //
.verifyComplete();
}
Mono<Void> bulkIndex(SampleEntity... entities) { Mono<Void> bulkIndex(SampleEntity... entities) {
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then(); return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then();
} }
@ -632,18 +720,39 @@ class SimpleReactiveElasticsearchRepositoryTests {
@CountQuery(value = "{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}") @CountQuery(value = "{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}")
Mono<Long> retrieveCountByText(String message); Mono<Long> retrieveCountByText(String message);
@Query("{ \"terms\": { \"message\": ?0 } }")
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageIn(List<String> messages);
@Query("{ \"terms\": { \"rate\": ?0 } }")
Flux<SampleEntity> findAllViaAnnotatedQueryByRatesIn(List<Integer> rates);
@Query("{\"bool\": {\"must\": [{ \"terms\": { \"message\": ?0 } }, { \"terms\": { \"rate\": ?1 } }] } }")
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageInAndRatesIn(List<String> messages, List<Integer> rates);
} }
@Document(indexName = INDEX) @Document(indexName = INDEX)
static class SampleEntity { static class SampleEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = Text, store = true, fielddata = true) private String type; @Id
@Nullable @Field(type = Text, store = true, fielddata = true) private String message; private String id;
@Nullable private int rate; @Nullable
@Nullable private boolean available; @Field(type = FieldType.Text, store = true, fielddata = true)
@Nullable @Version private Long version; private String type;
@Nullable
@Field(type = FieldType.Text, store = true, fielddata = true)
private String message;
@Nullable
private int rate;
@Nullable
private boolean available;
@Nullable
@Version
private Long version;
public SampleEntity() {} public SampleEntity() {
}
public SampleEntity(@Nullable String id) { public SampleEntity(@Nullable String id) {
this.id = id; this.id = id;