filter(Criteria criteria) {
+ return this.stream().filter(c -> c != criteria).collect(Collectors.toList());
+ }
+ }
/**
* Operator to join the entries of the criteria chain
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java
index d96fed8c7c..40f75e60b0 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java
@@ -19,11 +19,11 @@
import java.util.EnumSet;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.Query.SearchType;
import org.springframework.data.elasticsearch.core.query.types.ConflictsType;
import org.springframework.data.elasticsearch.core.query.types.OperatorType;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DocValueField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DocValueField.java
index 4ac86722fa..d35af8b280 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/DocValueField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DocValueField.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java
index ed3be07273..e6ffa17ed6 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java
@@ -17,7 +17,7 @@
import java.util.function.Function;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java
index 6897365119..cccb2a72b5 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* SourceFilter builder for providing includes and excludes.
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java
index 77c8ea45cd..cbfc5ea4f8 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.FieldType;
-import org.springframework.lang.Nullable;
/**
* Defines a Field that can be used within a Criteria.
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HasChildQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HasChildQuery.java
index 5fe4d5a122..17ce512c48 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/HasChildQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HasChildQuery.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HasParentQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HasParentQuery.java
index 0d8f9fb731..7e182c7e81 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/HasParentQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HasParentQuery.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java
index 370afcd2c1..5e8e2a5a70 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java
index 38e358bcaf..cad53334af 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* IndexQuery
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java
index 8cc67b2867..6e45280439 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java
@@ -15,8 +15,8 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
-import org.springframework.lang.Nullable;
/**
* IndexQuery Builder
@@ -36,7 +36,7 @@ public class IndexQueryBuilder {
@Nullable private Long seqNo;
@Nullable private Long primaryTerm;
@Nullable private String routing;
- @Nullable private IndexQuery.OpType opType;
+ private IndexQuery.@Nullable OpType opType;
@Nullable private RefreshPolicy refreshPolicy;
@Nullable private String indexName;
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/InnerHitsQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/InnerHitsQuery.java
index d4a92954d4..5097e72171 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/InnerHitsQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/InnerHitsQuery.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Defines an inner_hits request.
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java
index 57ce6ea34a..421e259403 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java
@@ -21,8 +21,8 @@
import java.util.ArrayList;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Pageable;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Order.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Order.java
index a3eaad2477..70044d2ed9 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/Order.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Order.java
@@ -17,8 +17,8 @@
import java.util.function.Function;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Sort;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java
index 2a0dd17b7b..ce3d445e1b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java
@@ -22,11 +22,11 @@
import java.util.List;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.SearchHit;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/RescorerQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/RescorerQuery.java
index c35725d1e0..96ce4a9f1b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/RescorerQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/RescorerQuery.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/RuntimeField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/RuntimeField.java
index 805883a5f9..2f7afcdb60 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/RuntimeField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/RuntimeField.java
@@ -18,7 +18,7 @@
import java.util.HashMap;
import java.util.Map;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptData.java b/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptData.java
index 0bcb6ad207..fc81b95d4a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptData.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptData.java
@@ -15,100 +15,110 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import org.jspecify.annotations.Nullable;
+import org.springframework.util.Assert;
+
import java.util.Map;
import java.util.function.Function;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
/**
* value class combining script information.
+ *
+ * A script is either an inline script, then the script parameters must be set
+ * or it refers to a stored script, then the name parameter is required.
*
+ * @param language the language when the script is passed in the script parameter
+ * @param script the script to use as inline script
+ * @param scriptName the name when using a stored script
+ * @param params the script parameters
* @author Peter-Josef Meisch
* @since 4.4
*/
-public record ScriptData(ScriptType type, @Nullable String language, @Nullable String script,
- @Nullable String scriptName, @Nullable Map params) {
-
- public ScriptData(ScriptType type, @Nullable String language, @Nullable String script, @Nullable String scriptName,
- @Nullable Map params) {
-
- Assert.notNull(type, "type must not be null");
-
- this.type = type;
- this.language = language;
- this.script = script;
- this.scriptName = scriptName;
- this.params = params;
- }
-
- /**
- * @since 5.2
- */
- public static ScriptData of(ScriptType type, @Nullable String language, @Nullable String script,
- @Nullable String scriptName, @Nullable Map params) {
- return new ScriptData(type, language, script, scriptName, params);
- }
-
- public static ScriptData of(Function builderFunction) {
-
- Assert.notNull(builderFunction, "f must not be null");
-
- return builderFunction.apply(new Builder()).build();
- }
-
- /**
- * @since 5.2
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * @since 5.2
- */
- public static final class Builder {
- @Nullable private ScriptType type;
- @Nullable private String language;
- @Nullable private String script;
- @Nullable private String scriptName;
- @Nullable private Map params;
-
- private Builder() {}
-
- public Builder withType(ScriptType type) {
-
- Assert.notNull(type, "type must not be null");
-
- this.type = type;
- return this;
- }
-
- public Builder withLanguage(@Nullable String language) {
- this.language = language;
- return this;
- }
-
- public Builder withScript(@Nullable String script) {
- this.script = script;
- return this;
- }
-
- public Builder withScriptName(@Nullable String scriptName) {
- this.scriptName = scriptName;
- return this;
- }
-
- public Builder withParams(@Nullable Map params) {
- this.params = params;
- return this;
- }
-
- public ScriptData build() {
-
- Assert.notNull(type, "type must be set");
-
- return new ScriptData(type, language, script, scriptName, params);
- }
- }
+public record ScriptData(@Nullable String language, @Nullable String script,
+ @Nullable String scriptName, @Nullable Map params) {
+
+ /*
+ * constructor overload to check the parameters
+ */
+ public ScriptData(@Nullable String language, @Nullable String script, @Nullable String scriptName,
+ @Nullable Map params) {
+
+ Assert.isTrue(script != null || scriptName != null, "script or scriptName is required");
+
+ this.language = language;
+ this.script = script;
+ this.scriptName = scriptName;
+ this.params = params;
+ }
+
+ /**
+ * factory method to create a ScriptData object.
+ *
+ * @since 5.2
+ */
+ public static ScriptData of(@Nullable String language, @Nullable String script,
+ @Nullable String scriptName, @Nullable Map params) {
+ return new ScriptData(language, script, scriptName, params);
+ }
+
+ /**
+ * factory method to create a ScriptData object using a ScriptBuilder callback.
+ *
+ * @param builderFunction function called to populate the builder
+ * @return
+ */
+ public static ScriptData of(Function builderFunction) {
+
+ Assert.notNull(builderFunction, "builderFunction must not be null");
+
+ return builderFunction.apply(new Builder()).build();
+ }
+
+ /**
+ * @since 5.2
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * @since 5.2
+ */
+ public static final class Builder {
+ @Nullable
+ private String language;
+ @Nullable
+ private String script;
+ @Nullable
+ private String scriptName;
+ @Nullable
+ private Map params;
+
+ private Builder() {
+ }
+
+ public Builder withLanguage(@Nullable String language) {
+ this.language = language;
+ return this;
+ }
+
+ public Builder withScript(@Nullable String script) {
+ this.script = script;
+ return this;
+ }
+
+ public Builder withScriptName(@Nullable String scriptName) {
+ this.scriptName = scriptName;
+ return this;
+ }
+
+ public Builder withParams(@Nullable Map params) {
+ this.params = params;
+ return this;
+ }
+
+ public ScriptData build() {
+ return new ScriptData(language, script, scriptName, params);
+ }
+ }
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQuery.java
index 4b4999fb05..804582c7bd 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQuery.java
@@ -17,7 +17,7 @@
import java.util.Map;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQueryBuilder.java
index 78fa4c3ad2..225933a677 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQueryBuilder.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SearchTemplateQueryBuilder.java
@@ -15,22 +15,22 @@
*/
package org.springframework.data.elasticsearch.core.query;
-import org.springframework.lang.Nullable;
-
import java.util.Map;
+import org.jspecify.annotations.Nullable;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+
/**
* @author Peter-Josef Meisch
* @since 5.1
*/
public class SearchTemplateQueryBuilder extends BaseQueryBuilder {
- @Nullable
- private String id;
+ @Nullable private String id;
@Nullable String source;
- @Nullable
- Map params;
+ @Nullable Map params;
@Nullable
public String getId() {
@@ -62,6 +62,18 @@ public SearchTemplateQueryBuilder withParams(@Nullable Map param
return this;
}
+ @Override
+ public SearchTemplateQueryBuilder withSort(Sort sort) {
+ throw new IllegalArgumentException(
+ "sort is not supported in a searchtemplate query. Sort values must be defined in the stored template");
+ }
+
+ @Override
+ public SearchTemplateQueryBuilder withPageable(Pageable pageable) {
+ throw new IllegalArgumentException(
+ "paging is not supported in a searchtemplate query. from and size values must be defined in the stored template");
+ }
+
@Override
public SearchTemplateQuery build() {
return new SearchTemplateQuery(this);
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java
index e943743654..298954cfa6 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java
@@ -15,12 +15,12 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import java.util.Objects;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.FieldType;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
-import java.util.Objects;
-
/**
* The most trivial implementation of a Field. The {@link #name} is updatable, so it may be changed during query
* preparation by the {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}.
@@ -84,9 +84,12 @@ public String toString() {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SimpleField that)) return false;
- return Objects.equals(name, that.name) && Objects.equals(fieldType, that.fieldType) && Objects.equals(path, that.path);
+ if (this == o)
+ return true;
+ if (!(o instanceof SimpleField that))
+ return false;
+ return Objects.equals(name, that.name) && Objects.equals(fieldType, that.fieldType)
+ && Objects.equals(path, that.path);
}
@Override
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java
index d981cf80b7..6696615964 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java
@@ -15,12 +15,12 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.Field;
-import org.springframework.lang.Nullable;
/**
* SourceFilter for providing includes and excludes. Using these helps in reducing the amount of data that is returned
- * from Elasticsearch especially when the stored docuements are large and only some fields from these documents are
+ * from Elasticsearch especially when the stored documents are large and only some fields from these documents are
* needed. If the SourceFilter includes the name of a property that has a different name mapped in Elasticsearch (see
* {@link Field#name()} this will automatically be mapped.
*
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SqlQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SqlQuery.java
index f14f1738e4..332ba69627 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/SqlQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SqlQuery.java
@@ -20,7 +20,7 @@
import java.util.List;
import java.util.TimeZone;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java
index 90f759749e..75959bb56a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java
@@ -18,9 +18,9 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.elasticsearch.core.document.Document;
-import org.springframework.lang.Nullable;
/**
* Defines an update request.
@@ -76,7 +76,7 @@ private UpdateQuery(String id, @Nullable String script, @Nullable Map
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java
index 59ee81f307..9ab2a3108d 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java
@@ -18,12 +18,12 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.data.repository.reactive.ReactiveSortingRepository;
-import org.springframework.lang.Nullable;
/**
* Elasticsearch specific {@link org.springframework.data.repository.Repository} interface with reactive support.
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java b/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java
index b86a7137c9..719905721d 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java
@@ -19,11 +19,11 @@
import java.util.Arrays;
+import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java
index 1a7c898aa4..270425b63b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.aot;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java
index f11afc98b3..b307ca9737 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.cdi;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java
index 9f8e266765..2278b3f140 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.config;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java
index 9d9e57ab26..14c68bac4f 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java
@@ -1,5 +1,5 @@
/**
* infrastructure to define the Elasticsearch mapping for an index.
*/
-@org.springframework.lang.NonNullApi
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java
index 4420c7e091..fae3b1992a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.elasticsearch.repository.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHitSupport;
@@ -24,13 +25,13 @@
import org.springframework.data.elasticsearch.core.query.BaseQuery;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.Query;
+import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.ResultProcessor;
import org.springframework.data.util.StreamUtils;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -49,11 +50,11 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
protected ElasticsearchQueryMethod queryMethod;
protected final ElasticsearchOperations elasticsearchOperations;
protected final ElasticsearchConverter elasticsearchConverter;
- protected final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ protected final ValueEvaluationContextProvider evaluationContextProvider;
public AbstractElasticsearchRepositoryQuery(ElasticsearchQueryMethod queryMethod,
ElasticsearchOperations elasticsearchOperations,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ValueEvaluationContextProvider evaluationContextProvider) {
Assert.notNull(queryMethod, "queryMethod must not be null");
Assert.notNull(elasticsearchOperations, "elasticsearchOperations must not be null");
@@ -114,11 +115,15 @@ public Object execute(Object[] parameters) {
: PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE));
result = StreamUtils.createStreamFromIterator(elasticsearchOperations.searchForStream(query, clazz, index));
} else if (queryMethod.isCollectionQuery()) {
- if (parameterAccessor.getPageable().isUnpaged()) {
- int itemCount = (int) elasticsearchOperations.count(query, clazz, index);
- query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
+ if (query instanceof SearchTemplateQuery) {
+ // we cannot get a count here, from and size would be in the template
} else {
- query.setPageable(parameterAccessor.getPageable());
+ if (parameterAccessor.getPageable().isUnpaged()) {
+ int itemCount = (int) elasticsearchOperations.count(query, clazz, index);
+ query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
+ } else {
+ query.setPageable(parameterAccessor.getPageable());
+ }
}
result = elasticsearchOperations.search(query, clazz, index);
} else {
@@ -137,7 +142,8 @@ public Query createQuery(Object[] parameters) {
var query = createQuery(parameterAccessor);
Assert.notNull(query, "unsupported query");
- queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter(),
+ queryMethod.addSpecialMethodParameters(query, parameterAccessor,
+ elasticsearchOperations.getElasticsearchConverter(),
evaluationContextProvider);
return query;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java
index 74d3e78d75..1d72522865 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java
@@ -32,10 +32,10 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchQueryExecution.ResultProcessingConverter;
import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchQueryExecution.ResultProcessingExecution;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.repository.query.ResultProcessor;
import org.springframework.util.Assert;
@@ -52,11 +52,11 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
protected final ReactiveElasticsearchQueryMethod queryMethod;
private final ReactiveElasticsearchOperations elasticsearchOperations;
- protected final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ protected final ValueEvaluationContextProvider evaluationContextProvider;
AbstractReactiveElasticsearchRepositoryQuery(ReactiveElasticsearchQueryMethod queryMethod,
ReactiveElasticsearchOperations elasticsearchOperations,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ValueEvaluationContextProvider evaluationContextProvider) {
Assert.notNull(queryMethod, "queryMethod must not be null");
Assert.notNull(elasticsearchOperations, "elasticsearchOperations must not be null");
@@ -105,7 +105,8 @@ private Object execute(ElasticsearchParametersParameterAccessor parameterAccesso
var query = createQuery(parameterAccessor);
Assert.notNull(query, "unsupported query");
- queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter(),
+ queryMethod.addSpecialMethodParameters(query, parameterAccessor,
+ elasticsearchOperations.getElasticsearchConverter(),
evaluationContextProvider);
String indexName = queryMethod.getEntityInformation().getIndexName();
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java
index f4bec2da9f..f06eba3084 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java
@@ -16,12 +16,7 @@
package org.springframework.data.elasticsearch.repository.query;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
-import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
-import org.springframework.data.elasticsearch.core.query.BaseQuery;
-import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
-import org.springframework.data.mapping.context.MappingContext;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.data.repository.query.parser.PartTree;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
* ElasticsearchPartQuery
@@ -33,42 +28,12 @@
* @author Rasmus Faber-Espensen
* @author Peter-Josef Meisch
* @author Haibo Liu
+ * @deprecated since 5.5, use {@link RepositoryPartQuery} instead
*/
-public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
-
- private final PartTree tree;
- private final MappingContext, ElasticsearchPersistentProperty> mappingContext;
-
+@Deprecated(forRemoval = true)
+public class ElasticsearchPartQuery extends RepositoryPartQuery {
public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOperations elasticsearchOperations,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
- super(method, elasticsearchOperations, evaluationContextProvider);
- this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
- this.mappingContext = elasticsearchConverter.getMappingContext();
- }
-
- @Override
- public boolean isCountQuery() {
- return tree.isCountProjection();
- }
-
- @Override
- protected boolean isDeleteQuery() {
- return tree.isDelete();
- }
-
- @Override
- protected boolean isExistsQuery() {
- return tree.isExistsProjection();
- }
-
- protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor accessor) {
-
- BaseQuery query = new ElasticsearchQueryCreator(tree, accessor, mappingContext).createQuery();
-
- if (tree.getMaxResults() != null) {
- query.setMaxResults(tree.getMaxResults());
- }
-
- return query;
+ ValueExpressionDelegate valueExpressionDelegate) {
+ super(method, elasticsearchOperations, valueExpressionDelegate);
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java
index 6b0f54311e..2ff4bc2365 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java
@@ -23,11 +23,13 @@
import java.util.List;
import java.util.stream.Stream;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.Query;
+import org.springframework.data.elasticsearch.annotations.SearchTemplateQuery;
import org.springframework.data.elasticsearch.annotations.SourceFilters;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
@@ -43,17 +45,16 @@
import org.springframework.data.elasticsearch.core.query.ScriptedField;
import org.springframework.data.elasticsearch.core.query.SourceFilter;
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.repository.query.ParametersSource;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.util.TypeInformation;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -84,6 +85,7 @@ public class ElasticsearchQueryMethod extends QueryMethod {
@Nullable private final Query queryAnnotation;
@Nullable private final Highlight highlightAnnotation;
@Nullable private final SourceFilters sourceFilters;
+ @Nullable private final SearchTemplateQuery searchTemplateQueryAnnotation;
public ElasticsearchQueryMethod(Method method, RepositoryMetadata repositoryMetadata, ProjectionFactory factory,
MappingContext extends ElasticsearchPersistentEntity>, ElasticsearchPersistentProperty> mappingContext) {
@@ -98,17 +100,11 @@ public ElasticsearchQueryMethod(Method method, RepositoryMetadata repositoryMeta
this.highlightAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Highlight.class);
this.sourceFilters = AnnotatedElementUtils.findMergedAnnotation(method, SourceFilters.class);
this.unwrappedReturnType = potentiallyUnwrapReturnTypeFor(repositoryMetadata, method);
+ this.searchTemplateQueryAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, SearchTemplateQuery.class);
verifyCountQueryTypes();
}
- @SuppressWarnings("removal")
- @Override
- @Deprecated
- protected Parameters, ?> createParameters(Method method, TypeInformation> domainType) {
- return new ElasticsearchParameters(ParametersSource.of(method));
- }
-
@Override
protected Parameters, ?> createParameters(ParametersSource parametersSource) {
return new ElasticsearchParameters(parametersSource);
@@ -125,12 +121,16 @@ protected void verifyCountQueryTypes() {
}
}
+ /**
+ * @return if the method is annotated with the {@link Query} annotation.
+ */
public boolean hasAnnotatedQuery() {
return this.queryAnnotation != null;
}
/**
- * @return the query String. Must not be {@literal null} when {@link #hasAnnotatedQuery()} returns true
+ * @return the query String defined in the {@link Query} annotation. Must not be {@literal null} when
+ * {@link #hasAnnotatedQuery()} returns true.
*/
@Nullable
public String getAnnotatedQuery() {
@@ -158,6 +158,27 @@ public HighlightQuery getAnnotatedHighlightQuery(HighlightConverter highlightCon
return new HighlightQuery(highlightConverter.convert(highlightAnnotation), getDomainClass());
}
+ /**
+ * @return if the method is annotated with the {@link SearchTemplateQuery} annotation.
+ * @since 5.5
+ */
+ public boolean hasAnnotatedSearchTemplateQuery() {
+ return this.searchTemplateQueryAnnotation != null;
+ }
+
+ /**
+ * @return the {@link SearchTemplateQuery} annotation
+ * @throws IllegalArgumentException if no {@link SearchTemplateQuery} annotation is present on the method
+ * @since 5.5
+ */
+ public SearchTemplateQuery getAnnotatedSearchTemplateQuery() {
+
+ Assert.isTrue(hasAnnotatedSearchTemplateQuery(), "no SearchTemplateQuery annotation present on " + getName());
+ Assert.notNull(searchTemplateQueryAnnotation, "highlsearchTemplateQueryAnnotationightAnnotation must not be null");
+
+ return searchTemplateQueryAnnotation;
+ }
+
/**
* @return the {@link ElasticsearchEntityMetadata} for the query methods {@link #getReturnedObjectType() return type}.
* @since 3.2
@@ -281,7 +302,7 @@ public boolean isNotSearchPageMethod() {
/**
* @return {@literal true} if the method is annotated with
- * {@link org.springframework.data.elasticsearch.annotations.CountQuery} or with {@link Query}(count =true)
+ * {@link org.springframework.data.elasticsearch.annotations.CountQuery} or with {@link Query}(count = true)
* @since 4.2
*/
public boolean hasCountQueryAnnotation() {
@@ -303,7 +324,7 @@ public boolean hasCountQueryAnnotation() {
@Nullable
SourceFilter getSourceFilter(ElasticsearchParametersParameterAccessor parameterAccessor,
ElasticsearchConverter converter,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ValueEvaluationContextProvider evaluationContextProvider) {
if (sourceFilters == null || (sourceFilters.includes().length == 0 && sourceFilters.excludes().length == 0)) {
return null;
@@ -326,7 +347,7 @@ SourceFilter getSourceFilter(ElasticsearchParametersParameterAccessor parameterA
}
private String[] mapParameters(String[] source, ElasticsearchParametersParameterAccessor parameterAccessor,
- ConversionService conversionService, QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ConversionService conversionService, ValueEvaluationContextProvider evaluationContextProvider) {
List fieldNames = new ArrayList<>();
@@ -377,9 +398,9 @@ private Class> potentiallyUnwrapReturnTypeFor(RepositoryMetadata metadata, Met
}
}
- void addMethodParameter(BaseQuery query, ElasticsearchParametersParameterAccessor parameterAccessor,
+ void addSpecialMethodParameters(BaseQuery query, ElasticsearchParametersParameterAccessor parameterAccessor,
ElasticsearchConverter elasticsearchConverter,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ValueEvaluationContextProvider evaluationContextProvider) {
if (hasAnnotatedHighlight()) {
var highlightQuery = getAnnotatedHighlightQuery(new HighlightConverter(parameterAccessor,
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java
index 4bbbefab66..32f7d32a72 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java
@@ -15,13 +15,8 @@
*/
package org.springframework.data.elasticsearch.repository.query;
-import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
-import org.springframework.data.elasticsearch.core.query.BaseQuery;
-import org.springframework.data.elasticsearch.core.query.StringQuery;
-import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.util.Assert;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
* ElasticsearchStringQuery
@@ -32,43 +27,12 @@
* @author Taylor Ono
* @author Peter-Josef Meisch
* @author Haibo Liu
+ * @deprecated since 5.5, use {@link RepositoryStringQuery}
*/
-public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQuery {
-
- private final String queryString;
-
+@Deprecated(since = "5.5", forRemoval = true)
+public class ElasticsearchStringQuery extends RepositoryStringQuery {
public ElasticsearchStringQuery(ElasticsearchQueryMethod queryMethod, ElasticsearchOperations elasticsearchOperations,
- String queryString, QueryMethodEvaluationContextProvider evaluationContextProvider) {
- super(queryMethod, elasticsearchOperations, evaluationContextProvider);
-
- Assert.notNull(queryString, "Query cannot be empty");
- Assert.notNull(evaluationContextProvider, "ExpressionEvaluationContextProvider must not be null");
-
- this.queryString = queryString;
- }
-
- @Override
- public boolean isCountQuery() {
- return queryMethod.hasCountQueryAnnotation();
- }
-
- @Override
- protected boolean isDeleteQuery() {
- return false;
- }
-
- @Override
- protected boolean isExistsQuery() {
- return false;
+ String queryString, ValueExpressionDelegate valueExpressionDelegate) {
+ super(queryMethod, elasticsearchOperations, queryString, valueExpressionDelegate);
}
-
- protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
- ConversionService conversionService = elasticsearchOperations.getElasticsearchConverter().getConversionService();
- var processed = new QueryStringProcessor(queryString, queryMethod, conversionService, evaluationContextProvider)
- .createQuery(parameterAccessor);
-
- return new StringQuery(processed)
- .addSort(parameterAccessor.getSort());
- }
-
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/HighlightConverter.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/HighlightConverter.java
index 843aadecd2..21b134b2bf 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/HighlightConverter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/HighlightConverter.java
@@ -25,8 +25,8 @@
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.util.Assert;
/**
@@ -38,13 +38,13 @@ public class HighlightConverter {
private final ElasticsearchParametersParameterAccessor parameterAccessor;
private final ConversionService conversionService;
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ private final ValueEvaluationContextProvider evaluationContextProvider;
private final QueryMethod queryMethod;
HighlightConverter(ElasticsearchParametersParameterAccessor parameterAccessor,
- ConversionService conversionService,
- QueryMethodEvaluationContextProvider evaluationContextProvider,
- QueryMethod queryMethod) {
+ ConversionService conversionService,
+ ValueEvaluationContextProvider evaluationContextProvider,
+ QueryMethod queryMethod) {
Assert.notNull(parameterAccessor, "parameterAccessor must not be null");
Assert.notNull(conversionService, "conversionService must not be null");
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java
index d66a0087e0..c166e7edd6 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java
@@ -15,12 +15,12 @@
*/
package org.springframework.data.elasticsearch.repository.query;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.repository.query.ResultProcessor;
import org.springframework.data.repository.query.ReturnedType;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java
index 320ff5cf66..422eb46dbb 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java
@@ -15,8 +15,6 @@
*/
package org.springframework.data.elasticsearch.repository.query;
-import static org.springframework.data.repository.util.ClassUtils.*;
-
import reactor.core.publisher.Mono;
import java.lang.reflect.Method;
@@ -36,6 +34,7 @@
import org.springframework.data.repository.util.ReactiveWrapperConverters;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.ReactiveWrappers;
+import org.springframework.data.util.ReflectionUtils;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.ClassUtils;
@@ -55,7 +54,7 @@ public ReactiveElasticsearchQueryMethod(Method method, RepositoryMetadata metada
super(method, metadata, factory, mappingContext);
- if (hasParameterOfType(method, Pageable.class)) {
+ if (ReflectionUtils.hasParameterOfType(method, Pageable.class)) {
TypeInformation> returnType = TypeInformation.fromReturnTypeOf(method);
boolean multiWrapper = ReactiveWrappers.isMultiValueType(returnType.getType());
@@ -75,7 +74,7 @@ public ReactiveElasticsearchQueryMethod(Method method, RepositoryMetadata metada
method));
}
- if (hasParameterOfType(method, Sort.class)) {
+ if (ReflectionUtils.hasParameterOfType(method, Sort.class)) {
throw new IllegalStateException(String.format("Method must not have Pageable *and* Sort parameter. "
+ "Use sorting capabilities on Pageable instead! Offending method: %s", method));
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java
index 3fbbfff539..f636a566d3 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java
@@ -15,68 +15,26 @@
*/
package org.springframework.data.elasticsearch.repository.query;
-import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
-import org.springframework.data.elasticsearch.core.query.BaseQuery;
-import org.springframework.data.elasticsearch.core.query.StringQuery;
-import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.util.Assert;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
* @author Christoph Strobl
* @author Taylor Ono
* @author Haibo Liu
* @since 3.2
+ * @deprecated since 5.5, use {@link ReactiveRepositoryStringQuery}
*/
-public class ReactiveElasticsearchStringQuery extends AbstractReactiveElasticsearchRepositoryQuery {
-
- private final String query;
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+@Deprecated(since = "5.5", forRemoval = true)
+public class ReactiveElasticsearchStringQuery extends ReactiveRepositoryStringQuery {
public ReactiveElasticsearchStringQuery(ReactiveElasticsearchQueryMethod queryMethod,
- ReactiveElasticsearchOperations operations, QueryMethodEvaluationContextProvider evaluationContextProvider) {
-
- this(queryMethod.getAnnotatedQuery(), queryMethod, operations, evaluationContextProvider);
+ ReactiveElasticsearchOperations operations, ValueExpressionDelegate valueExpressionDelegate) {
+ super(queryMethod, operations, valueExpressionDelegate);
}
public ReactiveElasticsearchStringQuery(String query, ReactiveElasticsearchQueryMethod queryMethod,
- ReactiveElasticsearchOperations operations, QueryMethodEvaluationContextProvider evaluationContextProvider) {
- super(queryMethod, operations, evaluationContextProvider);
-
- Assert.notNull(query, "query must not be null");
- Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
-
- this.query = query;
- this.evaluationContextProvider = evaluationContextProvider;
- }
-
- @Override
- protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
- ConversionService conversionService = getElasticsearchOperations().getElasticsearchConverter()
- .getConversionService();
- String processed = new QueryStringProcessor(query, queryMethod, conversionService, evaluationContextProvider)
- .createQuery(parameterAccessor);
- return new StringQuery(processed);
- }
-
- @Override
- boolean isCountQuery() {
- return queryMethod.hasCountQueryAnnotation();
- }
-
- @Override
- boolean isDeleteQuery() {
- return false;
- }
-
- @Override
- boolean isExistsQuery() {
- return false;
- }
-
- @Override
- boolean isLimiting() {
- return false;
+ ReactiveElasticsearchOperations operations, ValueExpressionDelegate valueExpressionDelegate) {
+ super(query, queryMethod, operations, valueExpressionDelegate);
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java
index 1b16e2e5a9..417106457a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java
@@ -19,8 +19,8 @@
import org.springframework.data.elasticsearch.core.query.BaseQuery;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.ResultProcessor;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
import org.springframework.data.repository.query.parser.PartTree;
/**
@@ -35,8 +35,9 @@ public class ReactivePartTreeElasticsearchQuery extends AbstractReactiveElastics
public ReactivePartTreeElasticsearchQuery(ReactiveElasticsearchQueryMethod queryMethod,
ReactiveElasticsearchOperations elasticsearchOperations,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
- super(queryMethod, elasticsearchOperations, evaluationContextProvider);
+ ValueExpressionDelegate valueExpressionDelegate) {
+ super(queryMethod, elasticsearchOperations,
+ valueExpressionDelegate.createValueContextProvider(queryMethod.getParameters()));
ResultProcessor processor = queryMethod.getResultProcessor();
this.tree = new PartTree(queryMethod.getName(), processor.getReturnedType().getDomainType());
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQuery.java
new file mode 100644
index 0000000000..12e09eebfc
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQuery.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2025 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.LinkedHashMap;
+import java.util.Map;
+
+import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.query.BaseQuery;
+import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+import org.springframework.util.Assert;
+
+/**
+ * A reactive repository query that uses a search template already stored in Elasticsearch.
+ *
+ * @author P.J. Meisch (pj.meisch@sothawo.com)
+ * @since 5.5
+ */
+public class ReactiveRepositorySearchTemplateQuery extends AbstractReactiveElasticsearchRepositoryQuery {
+
+ private String id;
+ private Map params;
+
+ public ReactiveRepositorySearchTemplateQuery(ReactiveElasticsearchQueryMethod queryMethod,
+ ReactiveElasticsearchOperations elasticsearchOperations,
+ ValueExpressionDelegate valueExpressionDelegate,
+ String id) {
+ super(queryMethod, elasticsearchOperations,
+ valueExpressionDelegate.createValueContextProvider(queryMethod.getParameters()));
+ Assert.hasLength(id, "id must not be null or empty");
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Map getParams() {
+ return params;
+ }
+
+ @Override
+ public boolean isCountQuery() {
+ return false;
+ }
+
+ @Override
+ protected boolean isDeleteQuery() {
+ return false;
+ }
+
+ @Override
+ protected boolean isExistsQuery() {
+ return false;
+ }
+
+ @Override
+ boolean isLimiting() {
+ return false;
+ }
+
+ @Override
+ protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
+
+ var searchTemplateParameters = new LinkedHashMap();
+ var values = parameterAccessor.getValues();
+
+ parameterAccessor.getParameters().forEach(parameter -> {
+ if (!parameter.isSpecialParameter() && parameter.getName().isPresent() && parameter.getIndex() <= values.length) {
+ searchTemplateParameters.put(parameter.getName().get(), values[parameter.getIndex()]);
+ }
+ });
+
+ return SearchTemplateQuery.builder()
+ .withId(id)
+ .withParams(searchTemplateParameters)
+ .build();
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQuery.java
new file mode 100644
index 0000000000..45b9e66e58
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQuery.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019-2024 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 org.springframework.core.convert.ConversionService;
+import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.query.BaseQuery;
+import org.springframework.data.elasticsearch.core.query.StringQuery;
+import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+import org.springframework.util.Assert;
+
+/**
+ * Was originally named ReactiveElasticsearchStringQuery.
+ *
+ * @author Christoph Strobl
+ * @author Taylor Ono
+ * @author Haibo Liu
+ * @since 3.2
+ */
+public class ReactiveRepositoryStringQuery extends AbstractReactiveElasticsearchRepositoryQuery {
+
+ private final String query;
+
+ public ReactiveRepositoryStringQuery(ReactiveElasticsearchQueryMethod queryMethod,
+ ReactiveElasticsearchOperations operations, ValueExpressionDelegate valueExpressionDelegate) {
+
+ this(queryMethod.getAnnotatedQuery(), queryMethod, operations, valueExpressionDelegate);
+ }
+
+ public ReactiveRepositoryStringQuery(String query, ReactiveElasticsearchQueryMethod queryMethod,
+ ReactiveElasticsearchOperations operations, ValueExpressionDelegate valueExpressionDelegate) {
+ super(queryMethod, operations, valueExpressionDelegate.createValueContextProvider(queryMethod.getParameters()));
+
+ Assert.notNull(query, "query must not be null");
+
+ this.query = query;
+ }
+
+ @Override
+ protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
+ ConversionService conversionService = getElasticsearchOperations().getElasticsearchConverter()
+ .getConversionService();
+ String processed = new QueryStringProcessor(query, queryMethod, conversionService, evaluationContextProvider)
+ .createQuery(parameterAccessor);
+ return new StringQuery(processed);
+ }
+
+ @Override
+ boolean isCountQuery() {
+ return queryMethod.hasCountQueryAnnotation();
+ }
+
+ @Override
+ boolean isDeleteQuery() {
+ return false;
+ }
+
+ @Override
+ boolean isExistsQuery() {
+ return false;
+ }
+
+ @Override
+ boolean isLimiting() {
+ return false;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryPartQuery.java
new file mode 100644
index 0000000000..578a30e9cb
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryPartQuery.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2013-2024 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 org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
+import org.springframework.data.elasticsearch.core.query.BaseQuery;
+import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
+import org.springframework.data.mapping.context.MappingContext;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+import org.springframework.data.repository.query.parser.PartTree;
+
+/**
+ * A repository query that is built from the the method name in the repository definition. Was originally named
+ * ElasticsearchPartQuery.
+ *
+ * @author Rizwan Idrees
+ * @author Mohsin Husen
+ * @author Kevin Leturc
+ * @author Mark Paluch
+ * @author Rasmus Faber-Espensen
+ * @author Peter-Josef Meisch
+ * @author Haibo Liu
+ */
+public class RepositoryPartQuery extends AbstractElasticsearchRepositoryQuery {
+
+ private final PartTree tree;
+ private final MappingContext, ElasticsearchPersistentProperty> mappingContext;
+
+ public RepositoryPartQuery(ElasticsearchQueryMethod method, ElasticsearchOperations elasticsearchOperations,
+ ValueExpressionDelegate valueExpressionDelegate) {
+ super(method, elasticsearchOperations,
+ valueExpressionDelegate.createValueContextProvider(method.getParameters()));
+ this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
+ this.mappingContext = elasticsearchConverter.getMappingContext();
+ }
+
+ @Override
+ public boolean isCountQuery() {
+ return tree.isCountProjection();
+ }
+
+ @Override
+ protected boolean isDeleteQuery() {
+ return tree.isDelete();
+ }
+
+ @Override
+ protected boolean isExistsQuery() {
+ return tree.isExistsProjection();
+ }
+
+ protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor accessor) {
+
+ BaseQuery query = new ElasticsearchQueryCreator(tree, accessor, mappingContext).createQuery();
+
+ if (tree.getMaxResults() != null) {
+ query.setMaxResults(tree.getMaxResults());
+ }
+
+ return query;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQuery.java
new file mode 100644
index 0000000000..ddec6e2f07
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQuery.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2025 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.LinkedHashMap;
+import java.util.Map;
+
+import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.query.BaseQuery;
+import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+import org.springframework.util.Assert;
+
+/**
+ * A repository query that uses a search template already stored in Elasticsearch.
+ *
+ * @author P.J. Meisch (pj.meisch@sothawo.com)
+ * @since 5.5
+ */
+public class RepositorySearchTemplateQuery extends AbstractElasticsearchRepositoryQuery {
+
+ private String id;
+ private Map params;
+
+ public RepositorySearchTemplateQuery(ElasticsearchQueryMethod queryMethod,
+ ElasticsearchOperations elasticsearchOperations, ValueExpressionDelegate valueExpressionDelegate,
+ String id) {
+ super(queryMethod, elasticsearchOperations,
+ valueExpressionDelegate.createValueContextProvider(queryMethod.getParameters()));
+ Assert.hasLength(id, "id must not be null or empty");
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Map getParams() {
+ return params;
+ }
+
+ @Override
+ public boolean isCountQuery() {
+ return false;
+ }
+
+ @Override
+ protected boolean isDeleteQuery() {
+ return false;
+ }
+
+ @Override
+ protected boolean isExistsQuery() {
+ return false;
+ }
+
+ @Override
+ protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
+
+ var searchTemplateParameters = new LinkedHashMap();
+ var values = parameterAccessor.getValues();
+
+ parameterAccessor.getParameters().forEach(parameter -> {
+ if (!parameter.isSpecialParameter() && parameter.getName().isPresent() && parameter.getIndex() <= values.length) {
+ searchTemplateParameters.put(parameter.getName().get(), values[parameter.getIndex()]);
+ }
+ });
+
+ return SearchTemplateQuery.builder()
+ .withId(id)
+ .withParams(searchTemplateParameters)
+ .build();
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQuery.java
new file mode 100644
index 0000000000..1b768b6ea7
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQuery.java
@@ -0,0 +1,57 @@
+package org.springframework.data.elasticsearch.repository.query;
+
+import org.springframework.core.convert.ConversionService;
+import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.query.BaseQuery;
+import org.springframework.data.elasticsearch.core.query.StringQuery;
+import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+import org.springframework.util.Assert;
+
+/**
+ * A repository query that is defined by a String containing the query. Was originally named ElasticsearchStringQuery.
+ *
+ * @author Rizwan Idrees
+ * @author Mohsin Husen
+ * @author Mark Paluch
+ * @author Taylor Ono
+ * @author Peter-Josef Meisch
+ * @author Haibo Liu
+ */
+public class RepositoryStringQuery extends AbstractElasticsearchRepositoryQuery {
+ private final String queryString;
+
+ public RepositoryStringQuery(ElasticsearchQueryMethod queryMethod, ElasticsearchOperations elasticsearchOperations,
+ String queryString, ValueExpressionDelegate valueExpressionDelegate) {
+ super(queryMethod, elasticsearchOperations,
+ valueExpressionDelegate.createValueContextProvider(queryMethod.getParameters()));
+
+ Assert.notNull(queryString, "Query cannot be empty");
+
+ this.queryString = queryString;
+ }
+
+ @Override
+ public boolean isCountQuery() {
+ return queryMethod.hasCountQueryAnnotation();
+ }
+
+ @Override
+ protected boolean isDeleteQuery() {
+ return false;
+ }
+
+ @Override
+ protected boolean isExistsQuery() {
+ return false;
+ }
+
+ protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
+ ConversionService conversionService = elasticsearchOperations.getElasticsearchConverter().getConversionService();
+ var processed = new QueryStringProcessor(queryString, queryMethod, conversionService, evaluationContextProvider)
+ .createQuery(parameterAccessor);
+
+ return new StringQuery(processed)
+ .addSort(parameterAccessor.getSort());
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java
index 0db3509f20..e903d1ffe1 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.query;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java
index e681d018d7..5c1456796a 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java
@@ -15,6 +15,10 @@
*/
package org.springframework.data.elasticsearch.repository.query.parser;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.geo.GeoBox;
@@ -31,10 +35,6 @@
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
import org.springframework.data.repository.query.parser.Part;
import org.springframework.data.repository.query.parser.PartTree;
-import org.springframework.lang.Nullable;
-
-import java.util.Collection;
-import java.util.Iterator;
/**
* ElasticsearchQueryCreator
@@ -48,159 +48,159 @@
*/
public class ElasticsearchQueryCreator extends AbstractQueryCreator {
- private final MappingContext, ElasticsearchPersistentProperty> context;
-
- public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
- MappingContext, ElasticsearchPersistentProperty> context) {
- super(tree, parameters);
- this.context = context;
- }
-
- public ElasticsearchQueryCreator(PartTree tree, MappingContext, ElasticsearchPersistentProperty> context) {
- super(tree);
- this.context = context;
- }
-
- @Override
- protected CriteriaQuery create(Part part, Iterator iterator) {
- PersistentPropertyPath path = context.getPersistentPropertyPath(
- part.getProperty());
- return new CriteriaQuery(from(part,
- new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
- iterator));
- }
-
- @Override
- protected CriteriaQuery and(Part part, CriteriaQuery base, Iterator iterator) {
- if (base == null) {
- return create(part, iterator);
- }
- PersistentPropertyPath path = context.getPersistentPropertyPath(
- part.getProperty());
- return base.addCriteria(from(part,
- new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
- iterator));
- }
-
- @Override
- protected CriteriaQuery or(CriteriaQuery base, CriteriaQuery query) {
- return new CriteriaQuery(base.getCriteria().or(query.getCriteria()));
- }
-
- @Override
- protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) {
-
- if (query == null) {
- // this is the case in a findAllByOrderByField method, add empty criteria
- query = new CriteriaQuery(new Criteria());
- }
- return query.addSort(sort);
- }
-
- private Criteria from(Part part, Criteria criteria, Iterator> parameters) {
-
- Part.Type type = part.getType();
-
- return switch (type) {
- case TRUE -> criteria.is(true);
- case FALSE -> criteria.is(false);
- case NEGATING_SIMPLE_PROPERTY -> criteria.is(parameters.next()).not();
- case REGEX -> criteria.expression(parameters.next().toString());
- case LIKE, STARTING_WITH -> criteria.startsWith(parameters.next().toString());
- case ENDING_WITH -> criteria.endsWith(parameters.next().toString());
- case CONTAINING -> criteria.contains(parameters.next().toString());
- case GREATER_THAN -> criteria.greaterThan(parameters.next());
- case AFTER, GREATER_THAN_EQUAL -> criteria.greaterThanEqual(parameters.next());
- case LESS_THAN -> criteria.lessThan(parameters.next());
- case BEFORE, LESS_THAN_EQUAL -> criteria.lessThanEqual(parameters.next());
- case BETWEEN -> criteria.between(parameters.next(), parameters.next());
- case IN -> criteria.in(asArray(parameters.next()));
- case NOT_IN -> criteria.notIn(asArray(parameters.next()));
- case SIMPLE_PROPERTY, WITHIN -> within(part, criteria, parameters);
- case NEAR -> near(criteria, parameters);
- case EXISTS, IS_NOT_NULL -> criteria.exists();
- case IS_NULL -> criteria.not().exists();
- case IS_EMPTY -> criteria.empty();
- case IS_NOT_EMPTY -> criteria.notEmpty();
- default -> throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
- };
- }
-
- private Criteria within(Part part, Criteria criteria, Iterator> parameters) {
-
- Object firstParameter = parameters.next();
- Object secondParameter;
-
- if (part.getType() == Part.Type.SIMPLE_PROPERTY) {
- if (part.getProperty().getType() != GeoPoint.class) {
- if (firstParameter != null) {
- return criteria.is(firstParameter);
- } else {
- // searching for null is a must_not (exists)
- return criteria.exists().not();
- }
- } else {
- // it means it's a simple find with exact geopoint matching (e.g. findByLocation)
- // and because Elasticsearch does not have any kind of query with just a geopoint
- // as argument we use a "geo distance" query with a distance of one meter.
- secondParameter = ".001km";
- }
- } else {
- secondParameter = parameters.next();
- }
-
- return doWithinIfPossible(criteria, firstParameter, secondParameter);
- }
-
- private Criteria near(Criteria criteria, Iterator> parameters) {
-
- Object firstParameter = parameters.next();
-
- if (firstParameter instanceof GeoBox geoBox) {
- return criteria.boundedBy(geoBox);
- }
-
- if (firstParameter instanceof Box box) {
- return criteria.boundedBy(GeoBox.fromBox(box));
- }
-
- Object secondParameter = parameters.next();
-
- return doWithinIfPossible(criteria, firstParameter, secondParameter);
- }
-
- /**
- * Do a within query if possible, otherwise return the criteria unchanged.
- *
- * @param criteria must not be {@literal null}
- * @param firstParameter must not be {@literal null}
- * @param secondParameter must not be {@literal null}
- * @return the criteria with the within query applied if possible.
- * @author Junghoon Ban
- */
- private Criteria doWithinIfPossible(Criteria criteria, Object firstParameter, Object secondParameter) {
-
- if (firstParameter instanceof GeoPoint geoPoint && secondParameter instanceof String string) {
- return criteria.within(geoPoint, string);
- }
-
- if (firstParameter instanceof Point point && secondParameter instanceof Distance distance) {
- return criteria.within(point, distance);
- }
-
- if (firstParameter instanceof String firstString && secondParameter instanceof String secondString) {
- return criteria.within(firstString, secondString);
- }
-
- return criteria;
- }
-
- private Object[] asArray(Object o) {
- if (o instanceof Collection) {
- return ((Collection>) o).toArray();
- } else if (o.getClass().isArray()) {
- return (Object[]) o;
- }
- return new Object[]{o};
- }
+ private final MappingContext, ElasticsearchPersistentProperty> context;
+
+ public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
+ MappingContext, ElasticsearchPersistentProperty> context) {
+ super(tree, parameters);
+ this.context = context;
+ }
+
+ public ElasticsearchQueryCreator(PartTree tree, MappingContext, ElasticsearchPersistentProperty> context) {
+ super(tree);
+ this.context = context;
+ }
+
+ @Override
+ protected CriteriaQuery create(Part part, Iterator iterator) {
+ PersistentPropertyPath path = context.getPersistentPropertyPath(
+ part.getProperty());
+ return new CriteriaQuery(from(part,
+ new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
+ iterator));
+ }
+
+ @Override
+ protected CriteriaQuery and(Part part, CriteriaQuery base, Iterator iterator) {
+ if (base == null) {
+ return create(part, iterator);
+ }
+ PersistentPropertyPath path = context.getPersistentPropertyPath(
+ part.getProperty());
+ return base.addCriteria(from(part,
+ new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)),
+ iterator));
+ }
+
+ @Override
+ protected CriteriaQuery or(CriteriaQuery base, CriteriaQuery query) {
+ return new CriteriaQuery(base.getCriteria().or(query.getCriteria()));
+ }
+
+ @Override
+ protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) {
+
+ if (query == null) {
+ // this is the case in a findAllByOrderByField method, add empty criteria
+ query = new CriteriaQuery(new Criteria());
+ }
+ return query.addSort(sort);
+ }
+
+ private Criteria from(Part part, Criteria criteria, Iterator> parameters) {
+
+ Part.Type type = part.getType();
+
+ return switch (type) {
+ case TRUE -> criteria.is(true);
+ case FALSE -> criteria.is(false);
+ case NEGATING_SIMPLE_PROPERTY -> criteria.is(parameters.next()).not();
+ case REGEX -> criteria.expression(parameters.next().toString());
+ case LIKE, STARTING_WITH -> criteria.startsWith(parameters.next().toString());
+ case ENDING_WITH -> criteria.endsWith(parameters.next().toString());
+ case CONTAINING -> criteria.contains(parameters.next().toString());
+ case GREATER_THAN -> criteria.greaterThan(parameters.next());
+ case AFTER, GREATER_THAN_EQUAL -> criteria.greaterThanEqual(parameters.next());
+ case LESS_THAN -> criteria.lessThan(parameters.next());
+ case BEFORE, LESS_THAN_EQUAL -> criteria.lessThanEqual(parameters.next());
+ case BETWEEN -> criteria.between(parameters.next(), parameters.next());
+ case IN -> criteria.in(asArray(parameters.next()));
+ case NOT_IN -> criteria.notIn(asArray(parameters.next()));
+ case SIMPLE_PROPERTY, WITHIN -> within(part, criteria, parameters);
+ case NEAR -> near(criteria, parameters);
+ case EXISTS, IS_NOT_NULL -> criteria.exists();
+ case IS_NULL -> criteria.not().exists();
+ case IS_EMPTY -> criteria.empty();
+ case IS_NOT_EMPTY -> criteria.notEmpty();
+ default -> throw new InvalidDataAccessApiUsageException("Illegal criteria found '" + type + "'.");
+ };
+ }
+
+ private Criteria within(Part part, Criteria criteria, Iterator> parameters) {
+
+ Object firstParameter = parameters.next();
+ Object secondParameter;
+
+ if (part.getType() == Part.Type.SIMPLE_PROPERTY) {
+ if (part.getProperty().getType() != GeoPoint.class) {
+ if (firstParameter != null) {
+ return criteria.is(firstParameter);
+ } else {
+ // searching for null is a must_not (exists)
+ return criteria.exists().not();
+ }
+ } else {
+ // it means it's a simple find with exact geopoint matching (e.g. findByLocation)
+ // and because Elasticsearch does not have any kind of query with just a geopoint
+ // as argument we use a "geo distance" query with a distance of one meter.
+ secondParameter = ".001km";
+ }
+ } else {
+ secondParameter = parameters.next();
+ }
+
+ return doWithinIfPossible(criteria, firstParameter, secondParameter);
+ }
+
+ private Criteria near(Criteria criteria, Iterator> parameters) {
+
+ Object firstParameter = parameters.next();
+
+ if (firstParameter instanceof GeoBox geoBox) {
+ return criteria.boundedBy(geoBox);
+ }
+
+ if (firstParameter instanceof Box box) {
+ return criteria.boundedBy(GeoBox.fromBox(box));
+ }
+
+ Object secondParameter = parameters.next();
+
+ return doWithinIfPossible(criteria, firstParameter, secondParameter);
+ }
+
+ /**
+ * Do a within query if possible, otherwise return the criteria unchanged.
+ *
+ * @param criteria must not be {@literal null}
+ * @param firstParameter must not be {@literal null}
+ * @param secondParameter must not be {@literal null}
+ * @return the criteria with the within query applied if possible.
+ * @author Junghoon Ban
+ */
+ private Criteria doWithinIfPossible(Criteria criteria, Object firstParameter, Object secondParameter) {
+
+ if (firstParameter instanceof GeoPoint geoPoint && secondParameter instanceof String string) {
+ return criteria.within(geoPoint, string);
+ }
+
+ if (firstParameter instanceof Point point && secondParameter instanceof Distance distance) {
+ return criteria.within(point, distance);
+ }
+
+ if (firstParameter instanceof String firstString && secondParameter instanceof String secondString) {
+ return criteria.within(firstString, secondString);
+ }
+
+ return criteria;
+ }
+
+ private Object[] asArray(Object o) {
+ if (o instanceof Collection) {
+ return ((Collection>) o).toArray();
+ } else if (o.getClass().isArray()) {
+ return (Object[]) o;
+ }
+ return new Object[] { o };
+ }
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java
index 1654f41ae7..5f524c1b89 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.query.parser;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java
index 6e71c428c9..1320b979fa 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java
@@ -15,10 +15,10 @@
*/
package org.springframework.data.elasticsearch.repository.support;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.repository.core.EntityInformation;
-import org.springframework.lang.Nullable;
/**
* @param
@@ -39,6 +39,5 @@ public interface ElasticsearchEntityInformation extends EntityInformation
@Nullable
Long getVersion(T entity);
- @Nullable
- Document.VersionType getVersionType();
+ Document.@Nullable VersionType getVersionType();
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java
index 321cbff344..b5d0b1270d 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java
@@ -20,11 +20,13 @@
import java.lang.reflect.Method;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
-import org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery;
import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod;
-import org.springframework.data.elasticsearch.repository.query.ElasticsearchStringQuery;
+import org.springframework.data.elasticsearch.repository.query.RepositoryPartQuery;
+import org.springframework.data.elasticsearch.repository.query.RepositorySearchTemplateQuery;
+import org.springframework.data.elasticsearch.repository.query.RepositoryStringQuery;
import org.springframework.data.elasticsearch.repository.support.querybyexample.QueryByExampleElasticsearchExecutor;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
@@ -37,9 +39,8 @@
import org.springframework.data.repository.query.QueryByExampleExecutor;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.lang.Nullable;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
import org.springframework.util.Assert;
/**
@@ -96,16 +97,16 @@ private static boolean isQueryDslRepository(Class> repositoryInterface) {
@Override
protected Optional getQueryLookupStrategy(@Nullable Key key,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
- return Optional.of(new ElasticsearchQueryLookupStrategy(evaluationContextProvider));
+ ValueExpressionDelegate valueExpressionDelegate) {
+ return Optional.of(new ElasticsearchQueryLookupStrategy(valueExpressionDelegate));
}
private class ElasticsearchQueryLookupStrategy implements QueryLookupStrategy {
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ private final ValueExpressionDelegate valueExpressionDelegate;
- ElasticsearchQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider) {
- this.evaluationContextProvider = evaluationContextProvider;
+ ElasticsearchQueryLookupStrategy(ValueExpressionDelegate valueExpressionDelegate) {
+ this.valueExpressionDelegate = valueExpressionDelegate;
}
/*
@@ -122,13 +123,17 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata,
if (namedQueries.hasQuery(namedQueryName)) {
String namedQuery = namedQueries.getQuery(namedQueryName);
- return new ElasticsearchStringQuery(queryMethod, elasticsearchOperations, namedQuery,
- evaluationContextProvider);
+ return new RepositoryStringQuery(queryMethod, elasticsearchOperations, namedQuery,
+ valueExpressionDelegate);
} else if (queryMethod.hasAnnotatedQuery()) {
- return new ElasticsearchStringQuery(queryMethod, elasticsearchOperations, queryMethod.getAnnotatedQuery(),
- evaluationContextProvider);
+ return new RepositoryStringQuery(queryMethod, elasticsearchOperations, queryMethod.getAnnotatedQuery(),
+ valueExpressionDelegate);
+ } else if (queryMethod.hasAnnotatedSearchTemplateQuery()) {
+ var searchTemplateQuery = queryMethod.getAnnotatedSearchTemplateQuery();
+ return new RepositorySearchTemplateQuery(queryMethod, elasticsearchOperations, valueExpressionDelegate,
+ searchTemplateQuery.id());
}
- return new ElasticsearchPartQuery(queryMethod, elasticsearchOperations, evaluationContextProvider);
+ return new RepositoryPartQuery(queryMethod, elasticsearchOperations, valueExpressionDelegate);
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java
index e331fa60e9..98cf29d0fc 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java
@@ -17,11 +17,11 @@
import java.io.Serializable;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/QueryStringProcessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/QueryStringProcessor.java
index bf00809915..b24cc17627 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/QueryStringProcessor.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/QueryStringProcessor.java
@@ -18,8 +18,8 @@
import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.repository.query.ElasticsearchParametersParameterAccessor;
import org.springframework.data.elasticsearch.repository.support.spel.QueryStringSpELEvaluator;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.util.Assert;
/**
@@ -34,10 +34,10 @@ public class QueryStringProcessor {
private final String query;
private final QueryMethod queryMethod;
private final ConversionService conversionService;
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ private final ValueEvaluationContextProvider evaluationContextProvider;
public QueryStringProcessor(String query, QueryMethod queryMethod, ConversionService conversionService,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
+ ValueEvaluationContextProvider evaluationContextProvider) {
Assert.notNull(query, "query must not be null");
Assert.notNull(queryMethod, "queryMethod must not be null");
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java
index 49e1e18fc3..368df504cf 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java
@@ -19,12 +19,14 @@
import java.lang.reflect.Method;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchQueryMethod;
-import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchStringQuery;
import org.springframework.data.elasticsearch.repository.query.ReactivePartTreeElasticsearchQuery;
+import org.springframework.data.elasticsearch.repository.query.ReactiveRepositorySearchTemplateQuery;
+import org.springframework.data.elasticsearch.repository.query.ReactiveRepositoryStringQuery;
import org.springframework.data.elasticsearch.repository.support.querybyexample.ReactiveQueryByExampleElasticsearchExecutor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.ProjectionFactory;
@@ -36,10 +38,9 @@
import org.springframework.data.repository.core.support.RepositoryFragment;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
import org.springframework.data.repository.query.RepositoryQuery;
-import org.springframework.lang.Nullable;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
import org.springframework.util.Assert;
/**
@@ -92,14 +93,10 @@ protected Object getTargetRepository(RepositoryInformation information) {
return getTargetRepositoryViaReflection(information, entityInformation, operations);
}
- /*
- * (non-Javadoc)
- * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
- */
@Override
protected Optional getQueryLookupStrategy(@Nullable Key key,
- QueryMethodEvaluationContextProvider evaluationContextProvider) {
- return Optional.of(new ElasticsearchQueryLookupStrategy(operations, evaluationContextProvider, mappingContext));
+ ValueExpressionDelegate valueExpressionDelegate) {
+ return Optional.of(new ElasticsearchQueryLookupStrategy(operations, valueExpressionDelegate, mappingContext));
}
/*
@@ -130,19 +127,19 @@ protected RepositoryMetadata getRepositoryMetadata(Class> repositoryInterface)
private static class ElasticsearchQueryLookupStrategy implements QueryLookupStrategy {
private final ReactiveElasticsearchOperations operations;
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ private final ValueExpressionDelegate valueExpressionDelegate;
private final MappingContext extends ElasticsearchPersistentEntity>, ElasticsearchPersistentProperty> mappingContext;
public ElasticsearchQueryLookupStrategy(ReactiveElasticsearchOperations operations,
- QueryMethodEvaluationContextProvider evaluationContextProvider,
+ ValueExpressionDelegate valueExpressionDelegate,
MappingContext extends ElasticsearchPersistentEntity>, ElasticsearchPersistentProperty> mappingContext) {
Assert.notNull(operations, "operations must not be null");
- Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
+ Assert.notNull(valueExpressionDelegate, "evaluationContextProvider must not be null");
Assert.notNull(mappingContext, "mappingContext must not be null");
this.operations = operations;
- this.evaluationContextProvider = evaluationContextProvider;
+ this.valueExpressionDelegate = valueExpressionDelegate;
this.mappingContext = mappingContext;
}
@@ -161,12 +158,16 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata,
if (namedQueries.hasQuery(namedQueryName)) {
String namedQuery = namedQueries.getQuery(namedQueryName);
- return new ReactiveElasticsearchStringQuery(namedQuery, queryMethod, operations,
- evaluationContextProvider);
+ return new ReactiveRepositoryStringQuery(namedQuery, queryMethod, operations,
+ valueExpressionDelegate);
} else if (queryMethod.hasAnnotatedQuery()) {
- return new ReactiveElasticsearchStringQuery(queryMethod, operations, evaluationContextProvider);
+ return new ReactiveRepositoryStringQuery(queryMethod, operations, valueExpressionDelegate);
+ } else if (queryMethod.hasAnnotatedSearchTemplateQuery()) {
+ var searchTemplateQuery = queryMethod.getAnnotatedSearchTemplateQuery();
+ return new ReactiveRepositorySearchTemplateQuery(queryMethod, operations, valueExpressionDelegate,
+ searchTemplateQuery.id());
} else {
- return new ReactivePartTreeElasticsearchQuery(queryMethod, operations, evaluationContextProvider);
+ return new ReactivePartTreeElasticsearchQuery(queryMethod, operations, valueExpressionDelegate);
}
}
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java
index b58bb3999b..3f30545bfb 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java
@@ -15,12 +15,12 @@
*/
package org.springframework.data.elasticsearch.repository.support;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java
index e58d9cc762..d48a3c80e5 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java
@@ -22,6 +22,7 @@
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
@@ -45,7 +46,6 @@
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.util.StreamUtils;
import org.springframework.data.util.Streamable;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -384,7 +384,7 @@ private void doDelete(@Nullable ID id, @Nullable String routing, IndexCoordinate
public void deleteAll() {
executeAndRefresh((OperationsCallback) operations -> {
- operations.delete(Query.findAll(), entityClass, getIndexCoordinates());
+ operations.delete(DeleteQuery.builder(Query.findAll()).build(), entityClass, getIndexCoordinates());
return null;
});
}
@@ -457,7 +457,7 @@ public R executeAndRefresh(OperationsCallback callback) {
@Nullable
public R executeAndRefresh(OperationsCallback callback, @Nullable RefreshPolicy refreshPolicy) {
- return callback.doWithOperations(operations.withRefreshPolicy(refreshPolicy));
+ return callback.doWithOperations(operations.withRefreshPolicy(refreshPolicy));
}
// endregion
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java
index 1d9c116cf6..ae3e1a4d00 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java
@@ -20,6 +20,7 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import org.jspecify.annotations.Nullable;
import org.reactivestreams.Publisher;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java
index 17be692af3..7f6a0f13f1 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/ExampleCriteriaMapper.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/ExampleCriteriaMapper.java
index cd3eefa925..432d1883e5 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/ExampleCriteriaMapper.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/ExampleCriteriaMapper.java
@@ -18,6 +18,7 @@
import java.util.Map;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
@@ -27,7 +28,6 @@
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.support.ExampleMatcherAccessor;
-import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/package-info.java
index aea4322e91..c2b3be5cca 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/querybyexample/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.querybyexample;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/QueryStringSpELEvaluator.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/QueryStringSpELEvaluator.java
index 3d691d3137..9d982d9281 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/QueryStringSpELEvaluator.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/QueryStringSpELEvaluator.java
@@ -18,14 +18,15 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.elasticsearch.core.convert.ConversionException;
import org.springframework.data.elasticsearch.repository.query.ElasticsearchParametersParameterAccessor;
import org.springframework.data.elasticsearch.repository.support.value.ElasticsearchCollectionValueToStringConverter;
import org.springframework.data.elasticsearch.repository.support.value.ElasticsearchQueryValueConversionService;
import org.springframework.data.elasticsearch.repository.support.value.ElasticsearchStringValueToStringConverter;
+import org.springframework.data.expression.ValueEvaluationContextProvider;
import org.springframework.data.repository.query.QueryMethod;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
@@ -36,7 +37,6 @@
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -53,11 +53,11 @@ public class QueryStringSpELEvaluator {
private final String queryString;
private final ElasticsearchParametersParameterAccessor parameterAccessor;
private final QueryMethod queryMethod;
- private final QueryMethodEvaluationContextProvider evaluationContextProvider;
+ private final ValueEvaluationContextProvider evaluationContextProvider;
private final TypeConverter elasticsearchSpELTypeConverter;
public QueryStringSpELEvaluator(String queryString, ElasticsearchParametersParameterAccessor parameterAccessor,
- QueryMethod queryMethod, QueryMethodEvaluationContextProvider evaluationContextProvider,
+ QueryMethod queryMethod, ValueEvaluationContextProvider evaluationContextProvider,
ConversionService conversionService) {
Assert.notNull(queryString, "queryString must not be null");
@@ -83,8 +83,8 @@ public String evaluate() {
Expression expr = getQueryExpression(queryString);
if (expr != null) {
- EvaluationContext context = evaluationContextProvider.getEvaluationContext(parameterAccessor.getParameters(),
- parameterAccessor.getValues());
+ EvaluationContext context = evaluationContextProvider.getEvaluationContext(parameterAccessor.getValues())
+ .getRequiredEvaluationContext();
if (context instanceof StandardEvaluationContext standardEvaluationContext) {
standardEvaluationContext.setTypeConverter(elasticsearchSpELTypeConverter);
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/package-info.java
index 1d76d236d8..0388eba7c4 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/spel/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.spel;
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchCollectionValueToStringConverter.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchCollectionValueToStringConverter.java
index 706e11de22..2e3441fd0e 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchCollectionValueToStringConverter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchCollectionValueToStringConverter.java
@@ -21,10 +21,10 @@
import java.util.Set;
import java.util.StringJoiner;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
-import org.springframework.lang.Nullable;
/**
* Convert a collection into string for value part of the elasticsearch query.
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchQueryValueConversionService.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchQueryValueConversionService.java
index 67540ee1fc..a611311c6f 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchQueryValueConversionService.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchQueryValueConversionService.java
@@ -18,11 +18,11 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchStringValueToStringConverter.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchStringValueToStringConverter.java
index 23b4a75de0..ee03ccf3fa 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchStringValueToStringConverter.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/ElasticsearchStringValueToStringConverter.java
@@ -19,9 +19,9 @@
import java.util.Set;
import java.util.regex.Matcher;
+import org.jspecify.annotations.Nullable;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
-import org.springframework.lang.Nullable;
/**
* Values in elasticsearch query may contain quotations and should be escaped when converting. Note that the converter
diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/package-info.java
index 89f2436e25..18e794112c 100644
--- a/src/main/java/org/springframework/data/elasticsearch/repository/support/value/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/value/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repository.support.value;
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/DefaultStringObjectMap.java b/src/main/java/org/springframework/data/elasticsearch/support/DefaultStringObjectMap.java
index a27aa036c6..f171d86048 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/DefaultStringObjectMap.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/DefaultStringObjectMap.java
@@ -22,7 +22,7 @@
import java.util.Set;
import java.util.function.BiConsumer;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/HttpHeaders.java b/src/main/java/org/springframework/data/elasticsearch/support/HttpHeaders.java
index 464b7253e1..742ce9d041 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/HttpHeaders.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/HttpHeaders.java
@@ -25,7 +25,7 @@
import java.util.Map;
import java.util.Set;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.MultiValueMap;
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/ScoreDoc.java b/src/main/java/org/springframework/data/elasticsearch/support/ScoreDoc.java
index c5079133f6..4de876f8ad 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/ScoreDoc.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/ScoreDoc.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.support;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/StringObjectMap.java b/src/main/java/org/springframework/data/elasticsearch/support/StringObjectMap.java
index 0cb286c7d9..f3a7c86c9b 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/StringObjectMap.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/StringObjectMap.java
@@ -21,8 +21,8 @@
import java.util.function.LongSupplier;
import java.util.function.Supplier;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.elasticsearch.core.document.Document;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java b/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java
index f9f85b6aac..d62ea73f87 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java
@@ -21,7 +21,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* This class is used to log the versions of Spring Data Elasticsearch, the Elasticsearch client libs used to built, the
diff --git a/src/main/java/org/springframework/data/elasticsearch/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/support/package-info.java
index 0ad015c73d..7c65e45ba3 100644
--- a/src/main/java/org/springframework/data/elasticsearch/support/package-info.java
+++ b/src/main/java/org/springframework/data/elasticsearch/support/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.support;
diff --git a/src/main/kotlin/org/springframework/data/elasticsearch/repository/CoroutineElasticsearchRepository.kt b/src/main/kotlin/org/springframework/data/elasticsearch/repository/CoroutineElasticsearchRepository.kt
index 221db17db9..79c932feab 100644
--- a/src/main/kotlin/org/springframework/data/elasticsearch/repository/CoroutineElasticsearchRepository.kt
+++ b/src/main/kotlin/org/springframework/data/elasticsearch/repository/CoroutineElasticsearchRepository.kt
@@ -24,4 +24,4 @@ import org.springframework.data.repository.kotlin.CoroutineSortingRepository
* @since 5.2
*/
@NoRepositoryBean
-interface CoroutineElasticsearchRepository : CoroutineCrudRepository, CoroutineSortingRepository
+interface CoroutineElasticsearchRepository : CoroutineCrudRepository, CoroutineSortingRepository
diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt
index 2e344df6d1..1966e7743c 100644
--- a/src/main/resources/notice.txt
+++ b/src/main/resources/notice.txt
@@ -1,4 +1,4 @@
-Spring Data Elasticsearch 5.4 GA (2024.1.0)
+Spring Data Elasticsearch 6.0 M3 (2025.1.0)
Copyright (c) [2013-2022] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -10,18 +10,3 @@ code for the these subcomponents is subject to the terms and
conditions of the subcomponent's license, as noted in the LICENSE file.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectIntegrationTests.java
index 991324cc8d..2682274550 100644
--- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectIntegrationTests.java
@@ -29,6 +29,7 @@
import java.util.Map;
import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -49,7 +50,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
diff --git a/src/test/java/org/springframework/data/elasticsearch/NullabilityArchitectureTests.java b/src/test/java/org/springframework/data/elasticsearch/NullabilityArchitectureTests.java
new file mode 100644
index 0000000000..a086f251e3
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/NullabilityArchitectureTests.java
@@ -0,0 +1,21 @@
+package org.springframework.data.elasticsearch;
+
+import com.tngtech.archunit.junit.AnalyzeClasses;
+import com.tngtech.archunit.junit.ArchTest;
+import com.tngtech.archunit.lang.ArchRule;
+import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
+
+@AnalyzeClasses(packages = { "org.springframework.data.elasticsearch" })
+class NullabilityArchitectureTests {
+
+ @ArchTest public static final ArchRule shouldNotUseSpringNullability = ArchRuleDefinition
+ .noClasses()
+ .that()
+ .resideInAPackage("org.springframework.data.elasticsearch..")
+ .should()
+ .dependOnClassesThat()
+ .haveFullyQualifiedName("org.springframework.lang.NonNull")
+ .orShould()
+ .dependOnClassesThat()
+ .haveFullyQualifiedName("org.springframework.lang.Nullable");
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/annotations/ComposableAnnotationsUnitTest.java b/src/test/java/org/springframework/data/elasticsearch/annotations/ComposableAnnotationsUnitTest.java
index e376c0beb6..8c64053a8c 100644
--- a/src/test/java/org/springframework/data/elasticsearch/annotations/ComposableAnnotationsUnitTest.java
+++ b/src/test/java/org/springframework/data/elasticsearch/annotations/ComposableAnnotationsUnitTest.java
@@ -28,6 +28,7 @@
import java.time.LocalDate;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AliasFor;
@@ -39,7 +40,6 @@
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.suggest.Completion;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryMappingUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryMappingUnitTests.java
index 88f9846147..c0f3641dbe 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryMappingUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/CriteriaQueryMappingUnitTests.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.elasticsearch.client.elc;
+import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
import static org.springframework.data.elasticsearch.client.elc.JsonUtils.*;
@@ -22,12 +23,14 @@
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import java.time.LocalDate;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.assertj.core.api.SoftAssertions;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -47,7 +50,6 @@
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.SourceFilter;
-import org.springframework.lang.Nullable;
/**
* Tests for the mapping of {@link CriteriaQuery} by a {@link MappingElasticsearchConverter}. In the same package as
@@ -445,6 +447,108 @@ void shouldMapNamesInSourceStoredFields() {
softly.assertAll();
}
+ // the following test failed because of a wrong implementation in Criteria
+ // equals and hscode methods.
+ @Test // #3083
+ @DisplayName("should map correct subcriteria")
+ void shouldMapCorrectSubcriteria() throws JSONException {
+ Criteria criteria = new Criteria("first").is("hello");
+
+ List criterias = new ArrayList<>();
+ criterias.add(new Criteria().or("second").exists());
+
+ List subCriterias = new ArrayList<>();
+ subCriterias.add(new Criteria("third").exists()
+ .and(new Criteria("fourth").is("ciao")));
+ subCriterias.add(new Criteria("third").exists()
+ .and(new Criteria("fourth").is("hi")));
+
+ Criteria result = Criteria.or();
+
+ for (Criteria c : criterias) {
+ result = result.or(c);
+ }
+
+ for (Criteria c : subCriterias) {
+ result = result.subCriteria(c);
+ }
+ criteria = criteria.subCriteria(result);
+ CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
+
+ String expected = """
+ {
+ "bool": {
+ "must": [
+ {
+ "query_string": {
+ "default_operator": "and",
+ "fields": [
+ "first"
+ ],
+ "query": "hello"
+ }
+ },
+ {
+ "bool": {
+ "should": [
+ {
+ "exists": {
+ "field": "second"
+ }
+ },
+ {
+ "bool": {
+ "must": [
+ {
+ "exists": {
+ "field": "third"
+ }
+ },
+ {
+ "query_string": {
+ "default_operator": "and",
+ "fields": [
+ "fourth"
+ ],
+ "query": "ciao"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "bool": {
+ "must": [
+ {
+ "exists": {
+ "field": "third"
+ }
+ },
+ {
+ "query_string": {
+ "default_operator": "and",
+ "fields": [
+ "fourth"
+ ],
+ "query": "hi"
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ """;
+
+ mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class);
+ var queryString = queryToJson(CriteriaQueryProcessor.createQuery(criteriaQuery.getCriteria()), mapper);
+
+ assertEquals(expected, queryString, false);
+ }
// endregion
// region helper functions
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/DevTests.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/DevTests.java
index d80e08ce98..25308b569a 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/DevTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/DevTests.java
@@ -48,6 +48,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.elasticsearch.client.RequestOptions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
@@ -57,7 +58,6 @@
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.support.HttpHeaders;
-import org.springframework.lang.Nullable;
/**
* Not really tests, but a class to check the first implementations of the new Elasticsearch client. Needs Elasticsearch
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/DocumentAdaptersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/DocumentAdaptersUnitTests.java
index 1b9e603397..68dc1db7c4 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/DocumentAdaptersUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/DocumentAdaptersUnitTests.java
@@ -23,6 +23,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.data.Offset;
@@ -144,17 +145,17 @@ void shouldAdaptReturnedMatchedQueries() {
Hit searchHit = new Hit.Builder() //
.index("index") //
.id("42") //
- .matchedQueries("query1", "query2") //
+ .matchedQueries("query1", 1D) //
.build();
SearchDocument searchDocument = DocumentAdapters.from(searchHit, jsonpMapper);
SoftAssertions softly = new SoftAssertions();
- List matchedQueries = searchDocument.getMatchedQueries();
+ Map matchedQueries = searchDocument.getMatchedQueries();
softly.assertThat(matchedQueries).isNotNull();
- softly.assertThat(matchedQueries).hasSize(2);
- softly.assertThat(matchedQueries).isEqualTo(Arrays.asList("query1", "query2"));
+ softly.assertThat(matchedQueries).hasSize(1);
+ softly.assertThat(matchedQueries).isEqualTo(Map.of("query1",1D));
softly.assertAll();
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/ELCWiremockTests.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/ELCWiremockTests.java
index 4e6c092300..875fd752eb 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/ELCWiremockTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/ELCWiremockTests.java
@@ -18,6 +18,7 @@
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -29,13 +30,13 @@
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
/**
* Tests that need to check the data produced by the Elasticsearch client
+ *
* @author Peter-Josef Meisch
*/
@SuppressWarnings("UastIncorrectHttpHeaderInspection")
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchPartQueryELCIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchPartQueryELCIntegrationTests.java
index 86b3958402..40f7dd7cee 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchPartQueryELCIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchPartQueryELCIntegrationTests.java
@@ -21,7 +21,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
-import org.springframework.data.elasticsearch.core.query.ElasticsearchPartQueryIntegrationTests;
+import org.springframework.data.elasticsearch.core.query.RepositoryPartQueryIntegrationTests;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
@@ -29,7 +29,7 @@
* @author Peter-Josef Meisch
* @since 4.4
*/
-public class ElasticsearchPartQueryELCIntegrationTests extends ElasticsearchPartQueryIntegrationTests {
+public class ElasticsearchPartQueryELCIntegrationTests extends RepositoryPartQueryIntegrationTests {
@Configuration
@Import({ ElasticsearchTemplateConfiguration.class })
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/elc/RequestConverterTest.java b/src/test/java/org/springframework/data/elasticsearch/client/elc/RequestConverterTest.java
index a789eb4ad2..cdb597e383 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/elc/RequestConverterTest.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/elc/RequestConverterTest.java
@@ -21,6 +21,7 @@
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.DocValueField;
import org.springframework.data.elasticsearch.core.query.StringQuery;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
@@ -83,8 +83,8 @@ void refreshSetByDeleteRequest() {
var deleteQuery = DeleteQuery.builder(query).withRefresh(true).build();
var deleteByQueryRequest = requestConverter.documentDeleteByQueryRequest(deleteQuery, null, SampleEntity.class,
- IndexCoordinates.of("foo"),
- null);
+ IndexCoordinates.of("foo"),
+ null);
assertThat(deleteByQueryRequest.refresh()).isTrue();
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java b/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java
index 79701328cb..3e0be80923 100644
--- a/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java
+++ b/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.client.util;
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTests.java
index 4ee583aaa0..eb27851084 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTests.java
@@ -20,6 +20,7 @@
import java.time.LocalDateTime;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.mapping.callback.EntityCallbacks;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/AuditingReactiveIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/AuditingReactiveIntegrationTest.java
index 2dfaee370e..84a308166d 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/AuditingReactiveIntegrationTest.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/AuditingReactiveIntegrationTest.java
@@ -21,6 +21,7 @@
import java.time.LocalDateTime;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/configuration/ElasticsearchConfigurationELCTests.java b/src/test/java/org/springframework/data/elasticsearch/config/configuration/ElasticsearchConfigurationELCTests.java
index 489daba24d..973f129b3a 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/configuration/ElasticsearchConfigurationELCTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/configuration/ElasticsearchConfigurationELCTests.java
@@ -20,6 +20,7 @@
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.elasticsearch.client.RestClient;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +32,6 @@
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/configuration/ReactiveElasticsearchConfigurationELCTests.java b/src/test/java/org/springframework/data/elasticsearch/config/configuration/ReactiveElasticsearchConfigurationELCTests.java
index a01485c995..77b290eeca 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/configuration/ReactiveElasticsearchConfigurationELCTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/configuration/ReactiveElasticsearchConfigurationELCTests.java
@@ -17,6 +17,7 @@
import static org.assertj.core.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,7 +30,6 @@
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedRepositoriesIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedRepositoriesIntegrationTests.java
index de50ad46e4..76bf50ccfe 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedRepositoriesIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedRepositoriesIntegrationTests.java
@@ -18,9 +18,7 @@
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
-import java.lang.Double;
-import java.lang.Long;
-
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -36,7 +34,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.repository.Repository;
-import org.springframework.lang.Nullable;
/**
* @author Kevin Leturc
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableRepositoriesIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableRepositoriesIntegrationTests.java
index a40aa5eaa4..8222e2ef82 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableRepositoriesIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableRepositoriesIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.UUID;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -40,7 +41,6 @@
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.repository.Repository;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
@@ -158,12 +158,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Double getScriptedRate() {
+ public java.lang.@Nullable Double getScriptedRate() {
return scriptedRate;
}
- public void setScriptedRate(@Nullable java.lang.Double scriptedRate) {
+ public void setScriptedRate(java.lang.@Nullable Double scriptedRate) {
this.scriptedRate = scriptedRate;
}
@@ -193,12 +192,11 @@ public void setLocation(@Nullable GeoPoint location) {
this.location = location;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -254,12 +252,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Long getScriptedRate() {
+ public java.lang.@Nullable Long getScriptedRate() {
return scriptedRate;
}
- public void setScriptedRate(@Nullable java.lang.Long scriptedRate) {
+ public void setScriptedRate(java.lang.@Nullable Long scriptedRate) {
this.scriptedRate = scriptedRate;
}
@@ -289,12 +286,11 @@ public void setLocation(@Nullable GeoPoint location) {
this.location = location;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java
index 55d936ed9f..c32f6a26e6 100644
--- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java
+++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.config.notnested;
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchELCIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchELCIntegrationTests.java
index a88a36dbb0..826c2e4166 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchELCIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchELCIntegrationTests.java
@@ -30,6 +30,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
@@ -45,11 +46,9 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
import org.springframework.data.elasticsearch.core.query.ScriptData;
-import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.core.query.ScriptedField;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
/**
@@ -183,7 +182,7 @@ protected Query getMatchAllQueryWithIncludesAndInlineExpressionScript(@Nullable
return nativeQueryBuilder.withScriptedField(new ScriptedField( //
fieldName, //
- new ScriptData(ScriptType.INLINE, "expression", script, null, params))) //
+ new ScriptData( "expression", script, null, params))) //
.build();
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java
index bac9a9b712..195b11b3d2 100755
--- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchIntegrationTests.java
@@ -24,13 +24,13 @@
import static org.springframework.data.elasticsearch.utils.IdGenerator.*;
import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
-import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.assertj.core.api.SoftAssertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -67,7 +67,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.util.StreamUtils;
-import org.springframework.lang.Nullable;
/**
* All the integration tests that are not in separate files.
@@ -1631,12 +1630,13 @@ void shouldDoUpdateByQueryForExistingDocument() {
final Query query = operations.matchAllQuery();
final UpdateQuery updateQuery = UpdateQuery.builder(query)
- .withScriptType(ScriptType.INLINE)
.withScript("ctx._source['message'] = params['newMessage']").withLang("painless")
.withParams(Collections.singletonMap("newMessage", messageAfterUpdate)).withAbortOnVersionConflict(true)
.build();
- operations.updateByQuery(updateQuery, IndexCoordinates.of(indexNameProvider.indexName()));
+ var byQueryResponse = operations.updateByQuery(updateQuery, IndexCoordinates.of(indexNameProvider.indexName()));
+
+ assertThat(byQueryResponse.getUpdated()).isEqualTo(1);
SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class,
IndexCoordinates.of(indexNameProvider.indexName()));
@@ -4002,12 +4002,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Double getScriptedRate() {
+ public java.lang.@Nullable Double getScriptedRate() {
return scriptedRate;
}
- public void setScriptedRate(@Nullable java.lang.Double scriptedRate) {
+ public void setScriptedRate(java.lang.@Nullable Double scriptedRate) {
this.scriptedRate = scriptedRate;
}
@@ -4028,12 +4027,11 @@ public void setLocation(@Nullable GeoPoint location) {
this.location = location;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
@@ -4162,12 +4160,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Long getScriptedRate() {
+ public java.lang.@Nullable Long getScriptedRate() {
return scriptedRate;
}
- public void setScriptedRate(@Nullable java.lang.Long scriptedRate) {
+ public void setScriptedRate(java.lang.@Nullable Long scriptedRate) {
this.scriptedRate = scriptedRate;
}
@@ -4188,12 +4185,11 @@ public void setLocation(@Nullable GeoPoint location) {
this.location = location;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -4339,12 +4335,11 @@ private static class GTEVersionEntity {
@Id private String id;
@Nullable private String name;
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
@@ -4399,12 +4394,11 @@ public void setFirstName(@Nullable String firstName) {
this.firstName = firstName;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -4442,12 +4436,11 @@ public void setLastName(@Nullable String lastName) {
this.lastName = lastName;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -4532,7 +4525,7 @@ static class SearchHitsEntity {
public SearchHitsEntity() {}
- public SearchHitsEntity(@Nullable String id, @Nullable java.lang.Long number, @Nullable String keyword) {
+ public SearchHitsEntity(@Nullable String id, java.lang.@Nullable Long number, @Nullable String keyword) {
this.id = id;
this.number = number;
this.keyword = keyword;
@@ -4547,12 +4540,11 @@ public void setId(@Nullable String id) {
this.id = id;
}
- @Nullable
- public java.lang.Long getNumber() {
+ public java.lang.@Nullable Long getNumber() {
return number;
}
- public void setNumber(@Nullable java.lang.Long number) {
+ public void setNumber(java.lang.@Nullable Long number) {
this.number = number;
}
@@ -4667,12 +4659,11 @@ public void setSeqNoPrimaryTerm(@Nullable SeqNoPrimaryTerm seqNoPrimaryTerm) {
this.seqNoPrimaryTerm = seqNoPrimaryTerm;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -4686,7 +4677,7 @@ static class VersionedEntity {
public VersionedEntity() {}
- public VersionedEntity(@Nullable String id, @Nullable java.lang.Long version) {
+ public VersionedEntity(@Nullable String id, java.lang.@Nullable Long version) {
this.id = id;
this.version = version;
}
@@ -4700,12 +4691,11 @@ public void setId(@Nullable String id) {
this.id = id;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -4823,7 +4813,7 @@ public static final class ImmutableWithScriptedEntity {
@Nullable
@ScriptedField private final Double scriptedRate;
- public ImmutableWithScriptedEntity(String id, int rate, @Nullable java.lang.Double scriptedRate) {
+ public ImmutableWithScriptedEntity(String id, int rate, java.lang.@Nullable Double scriptedRate) {
this.id = id;
this.rate = rate;
this.scriptedRate = scriptedRate;
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/EntityOperationsUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/EntityOperationsUnitTests.java
index c7ada87d8e..c85621b8bb 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/EntityOperationsUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/EntityOperationsUnitTests.java
@@ -21,6 +21,7 @@
import java.util.HashSet;
import org.assertj.core.api.SoftAssertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -39,7 +40,6 @@
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
import org.springframework.data.elasticsearch.core.routing.DefaultRoutingResolver;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsIntegrationTests.java
index 1f50ee60fe..6dcb12cb7e 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.List;
import org.assertj.core.api.SoftAssertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Testing the querying and parsing of inner_hits.
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityIntegrationTests.java
index c189c68634..c7c7c463cf 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.Arrays;
import java.util.Date;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* LogEntityIntegrationTests
@@ -137,8 +137,7 @@ static class LogEntity {
@Nullable private long sequenceCode;
@Nullable
@Field(type = Ip) private String ip;
- @Nullable
- @Field(type = Date, format = DateFormat.date_time) private java.util.Date date;
+ @Field(type = Date, format = DateFormat.date_time) private java.util.@Nullable Date date;
private LogEntity() {}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/PointInTimeIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/PointInTimeIntegrationTests.java
index 63ec4fec90..4f640f8432 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/PointInTimeIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/PointInTimeIntegrationTests.java
@@ -19,6 +19,7 @@
import java.time.Duration;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchELCIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchELCIntegrationTests.java
index f6ead65ff2..4e465de688 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchELCIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchELCIntegrationTests.java
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
@@ -42,7 +43,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java
index e39131dfad..7090ea5073 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java
@@ -42,6 +42,7 @@
import org.assertj.core.api.InstanceOfAssertFactories;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -74,7 +75,6 @@
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -1335,12 +1335,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
@@ -1448,12 +1447,11 @@ public void setSeqNoPrimaryTerm(@Nullable SeqNoPrimaryTerm seqNoPrimaryTerm) {
this.seqNoPrimaryTerm = seqNoPrimaryTerm;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
@@ -1474,12 +1472,11 @@ public void setId(@Nullable String id) {
this.id = id;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactivePointInTimeIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactivePointInTimeIntegrationTests.java
index b6b2695929..e8163f8999 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReactivePointInTimeIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactivePointInTimeIntegrationTests.java
@@ -21,6 +21,7 @@
import java.time.Duration;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveReindexIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveReindexIntegrationTests.java
index e1dddee382..43e5019363 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveReindexIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveReindexIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.regex.Pattern;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* x * Note: the imperative version of these tests have more details and test methods, but they test that the request is
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveSearchTemplateIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveSearchTemplateIntegrationTests.java
index 7b3abbd9ec..f9f143d7d0 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveSearchTemplateIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveSearchTemplateIntegrationTests.java
@@ -25,6 +25,7 @@
import java.util.Map;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -40,7 +41,6 @@
import org.springframework.data.elasticsearch.core.script.Script;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Integration tests for the point in time API.
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReindexIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReindexIntegrationTests.java
index 03d2485ef4..2e77781087 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/ReindexIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/ReindexIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.regex.Pattern;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -34,7 +35,6 @@
import org.springframework.data.elasticsearch.core.reindex.ReindexResponse;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeIntegrationTests.java
index 429abe9199..b463ecaab9 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.Objects;
import java.util.stream.Collectors;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Aleksei Arsenev
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchTemplateIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchTemplateIntegrationTests.java
index e6339c2087..e22c6e3b4f 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/SearchTemplateIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchTemplateIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.Map;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.script.Script;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Integration tests search template API.
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SourceFilterIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SourceFilterIntegrationTests.java
index 11137ce88d..f08bc810a0 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/SourceFilterIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/SourceFilterIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.Collections;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.core.query.SourceFilter;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
@@ -208,7 +208,7 @@ void shouldNotReturnAnyFieldsWhenSourceIsSetToFalse() {
void shouldReturnAllFieldsWhenSourceIsSetToTrue() {
Query query = Query.findAll();
- query.addSourceFilter(FetchSourceFilter.of(b -> b.withFetchSource(true)));
+ query.addSourceFilter(FetchSourceFilter.of(b -> b.withFetchSource(true)));
SearchHits entities = operations.search(query, Entity.class);
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregationIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregationIntegrationTests.java
index ec6fa95fb8..106eb31233 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregationIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregationIntegrationTests.java
@@ -17,12 +17,11 @@
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
-import static org.springframework.data.elasticsearch.annotations.FieldType.Integer;
-import java.lang.Integer;
import java.util.ArrayList;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -41,7 +40,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java
index 985a17ad30..659e461d9b 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java
@@ -30,6 +30,7 @@
import org.intellij.lang.annotations.Language;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -73,7 +74,6 @@
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -1807,18 +1807,16 @@ void shouldReadASingleStringIntoAListPropertyImmutable() {
void shouldPopulateScriptedFields() {
SearchDocumentAdapter document = new SearchDocumentAdapter(Document.create(),
0.0f,
- new Object[]{},
+ new Object[] {},
Map.of(
- "scriptedField" , List.of("scriptedField"),
- "custom-name-scripted-field" , List.of("custom-name-scripted-field")
- ),
+ "scriptedField", List.of("scriptedField"),
+ "custom-name-scripted-field", List.of("custom-name-scripted-field")),
emptyMap(),
emptyMap(),
null,
null,
null,
- null
- );
+ null);
// Create a SearchDocument instance
var entity = mappingElasticsearchConverter.read(ScriptedEntity.class, document);
assertThat(entity.customScriptedField).isEqualTo("custom-name-scripted-field");
@@ -1826,8 +1824,7 @@ void shouldPopulateScriptedFields() {
}
static class ScriptedEntity {
- @ScriptedField
- private String scriptedField;
+ @ScriptedField private String scriptedField;
@ScriptedField(name = "custom-name-scripted-field") String customScriptedField;
ScriptedEntity() {
@@ -1853,9 +1850,11 @@ public void setCustomScriptedField(String customScriptedField) {
@Override
public boolean equals(Object o) {
- if (o == null || getClass() != o.getClass()) return false;
+ if (o == null || getClass() != o.getClass())
+ return false;
ScriptedEntity that = (ScriptedEntity) o;
- return Objects.equals(scriptedField, that.scriptedField) && Objects.equals(customScriptedField, that.customScriptedField);
+ return Objects.equals(scriptedField, that.scriptedField)
+ && Objects.equals(customScriptedField, that.customScriptedField);
}
@Override
@@ -1864,7 +1863,6 @@ public int hashCode() {
}
}
-
@Test // #2280
@DisplayName("should read a String array into a List property immutable")
void shouldReadAStringArrayIntoAListPropertyImmutable() {
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/PropertyValueConvertersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/PropertyValueConvertersUnitTests.java
index 273e0cf420..9465a1bd49 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/convert/PropertyValueConvertersUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/PropertyValueConvertersUnitTests.java
@@ -23,6 +23,7 @@
import java.util.List;
import java.util.stream.Stream;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Named;
import org.junit.jupiter.params.ParameterizedTest;
@@ -33,7 +34,6 @@
import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchPersistentEntity;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java
index f3e0e29698..d95c342321 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java
@@ -21,6 +21,7 @@
import java.time.LocalDateTime;
import java.util.Objects;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -34,7 +35,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/CallbackIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/CallbackIntegrationTests.java
index 991b31c6d5..86ae92305e 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/event/CallbackIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/event/CallbackIntegrationTests.java
@@ -21,6 +21,7 @@
import java.util.Collections;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -41,7 +42,6 @@
import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
/**
@@ -240,7 +240,7 @@ static class SampleEntity {
@Id private String id;
@Nullable private String text;
-// @ReadOnlyProperty
+ // @ReadOnlyProperty
@Nullable private String className;
@Nullable
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java
index d00a8d690e..aafc41293f 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java
@@ -24,6 +24,7 @@
import java.time.LocalDateTime;
import java.util.Objects;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.mapping.context.PersistentEntities;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveCallbackIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveCallbackIntegrationTests.java
index eb5f7f407c..de896111cb 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveCallbackIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveCallbackIntegrationTests.java
@@ -21,6 +21,7 @@
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -33,7 +34,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoIntegrationTests.java
index 20e3b6eb52..786afe8e74 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -39,7 +40,6 @@
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.elasticsearch.utils.geohash.Geohash;
import org.springframework.data.geo.Point;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonEntity.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonEntity.java
index 87c1fd095f..b18e02ed63 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonEntity.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonEntity.java
@@ -17,10 +17,10 @@
import java.util.Objects;
+import org.jspecify.annotations.Nullable;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.geo.Point;
-import org.springframework.lang.Nullable;
/**
* this class contains each GeoJson type as explicit type and as GeoJson interface. Used by several test classes
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonIntegrationTests.java
index 8a5e789039..633aa97aa9 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/GeoJsonIntegrationTests.java
@@ -19,6 +19,7 @@
import java.util.Arrays;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.geo.Point;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/IndexOperationsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/IndexOperationsIntegrationTests.java
index 3e2c8101d1..0431ec73a6 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/IndexOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/IndexOperationsIntegrationTests.java
@@ -26,6 +26,7 @@
import org.assertj.core.api.InstanceOfAssertFactories;
import org.assertj.core.api.SoftAssertions;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -47,7 +48,6 @@
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/IndexTemplateIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/IndexTemplateIntegrationTests.java
index 06209cc245..8d73d60790 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/IndexTemplateIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/IndexTemplateIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.UUID;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java
index 36efe8182c..c65867fe4d 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java
@@ -30,6 +30,7 @@
import java.util.Map;
import java.util.Set;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -43,7 +44,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Stuart Stevenson
@@ -711,12 +711,11 @@ public void setText(@Nullable String text) {
this.text = text;
}
- @Nullable
- public java.lang.Object getObject() {
+ public java.lang.@Nullable Object getObject() {
return object;
}
- public void setObject(@Nullable java.lang.Object object) {
+ public void setObject(java.lang.@Nullable Object object) {
this.object = object;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderUnitTests.java
index 673d56b1f5..d7a1e30a84 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderUnitTests.java
@@ -31,6 +31,7 @@
import java.util.Map;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
@@ -47,7 +48,6 @@
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.mapping.MappingException;
-import org.springframework.lang.Nullable;
/**
* @author Stuart Stevenson
@@ -1126,49 +1126,49 @@ void shouldAddFieldsThatAreExcludedFromSource() throws JSONException {
String expected = """
{
- "properties": {
- "_class": {
- "type": "keyword",
- "index": false,
- "doc_values": false
- },
- "excluded-date": {
- "type": "date",
- "format": "date"
- },
- "nestedEntity": {
- "type": "nested",
- "properties": {
- "_class": {
- "type": "keyword",
- "index": false,
- "doc_values": false
- },
- "excluded-text": {
- "type": "text"
- }
- }
- },
- "excluded-multifield": {
- "type": "text",
- "fields": {
- "keyword": {
- "type": "keyword"
- }
- }
- }
- },
- "_source": {
- "excludes": [
- "excluded-date",
- "nestedEntity.excluded-text",
- "excluded-multifield"
- ]
- }
+ "properties": {
+ "_class": {
+ "type": "keyword",
+ "index": false,
+ "doc_values": false
+ },
+ "excluded-date": {
+ "type": "date",
+ "format": "date"
+ },
+ "nestedEntity": {
+ "type": "nested",
+ "properties": {
+ "_class": {
+ "type": "keyword",
+ "index": false,
+ "doc_values": false
+ },
+ "excluded-text": {
+ "type": "text"
+ }
+ }
+ },
+ "excluded-multifield": {
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ }
+ }
+ },
+ "_source": {
+ "excludes": [
+ "excluded-date",
+ "nestedEntity.excluded-text",
+ "excluded-multifield"
+ ]
+ }
}
-
- """; //
+
+ """; //
String mapping = getMappingBuilder().buildPropertyMapping(ExcludedFieldEntity.class);
@@ -2141,21 +2141,19 @@ public void setId(@Nullable String id) {
this.id = id;
}
- @Nullable
- public java.lang.Integer getPageRank() {
+ public java.lang.@Nullable Integer getPageRank() {
return pageRank;
}
- public void setPageRank(@Nullable java.lang.Integer pageRank) {
+ public void setPageRank(java.lang.@Nullable Integer pageRank) {
this.pageRank = pageRank;
}
- @Nullable
- public java.lang.Integer getUrlLength() {
+ public java.lang.@Nullable Integer getUrlLength() {
return urlLength;
}
- public void setUrlLength(@Nullable java.lang.Integer urlLength) {
+ public void setUrlLength(java.lang.@Nullable Integer urlLength) {
this.urlLength = urlLength;
}
@@ -2309,12 +2307,11 @@ public void setText(@Nullable String text) {
this.text = text;
}
- @Nullable
- public java.lang.Object getObject() {
+ public java.lang.@Nullable Object getObject() {
return object;
}
- public void setObject(@Nullable java.lang.Object object) {
+ public void setObject(java.lang.@Nullable Object object) {
this.object = object;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java
index 7d424d0498..1a41c64879 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java
@@ -2,10 +2,10 @@
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
-import static org.springframework.data.elasticsearch.annotations.FieldType.Object;
import java.lang.annotation.Annotation;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.elasticsearch.annotations.Field;
@@ -14,7 +14,6 @@
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexOperationsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexOperationsIntegrationTests.java
index ef892bc457..ba83137035 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexOperationsIntegrationTests.java
@@ -29,6 +29,7 @@
import org.assertj.core.api.InstanceOfAssertFactories;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -50,7 +51,6 @@
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexTemplateIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexTemplateIntegrationTests.java
index b832a32853..4cb0383248 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexTemplateIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveIndexTemplateIntegrationTests.java
@@ -27,6 +27,7 @@
import org.assertj.core.api.SoftAssertions;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -46,7 +47,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveMappingBuilderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveMappingBuilderUnitTests.java
index d9a9449277..d2b171d283 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveMappingBuilderUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/ReactiveMappingBuilderUnitTests.java
@@ -25,6 +25,7 @@
import java.util.List;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java
index 2026a58157..c827bef665 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java
@@ -21,6 +21,7 @@
import java.util.Map;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@@ -29,7 +30,6 @@
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
-import org.springframework.lang.Nullable;
/**
* Dynamic templates tests
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java
index f45158c936..a4a963c711 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java
@@ -21,6 +21,7 @@
import java.time.LocalDateTime;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
@@ -28,7 +29,6 @@
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.MappingContextBaseTests;
-import org.springframework.lang.Nullable;
/**
* @author Jakub Vavrik
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/EntityCustomConversionIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/EntityCustomConversionIntegrationTests.java
index 9ad3d83374..19da497cd9 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/EntityCustomConversionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/EntityCustomConversionIntegrationTests.java
@@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Objects;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -39,7 +40,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Test that a whole entity can be converted using custom conversions
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/FieldNamingStrategyIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/FieldNamingStrategyIntegrationTests.java
index 2ee3e39abd..35964e683f 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/FieldNamingStrategyIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/FieldNamingStrategyIntegrationTests.java
@@ -17,6 +17,7 @@
import static org.assertj.core.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -32,7 +33,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/ReactiveFieldNamingStrategyIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/ReactiveFieldNamingStrategyIntegrationTests.java
index 61f839cdf1..374a610e1d 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/ReactiveFieldNamingStrategyIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/ReactiveFieldNamingStrategyIntegrationTests.java
@@ -19,6 +19,7 @@
import reactor.test.StepVerifier;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -32,7 +33,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java
index 858ccaaa54..7c59723d3a 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java
@@ -19,6 +19,7 @@
import static org.skyscreamer.jsonassert.JSONAssert.*;
import org.json.JSONException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -37,7 +38,6 @@
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
-import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
/**
@@ -172,7 +172,7 @@ void shouldErrorIfIndexSortingParametersDoNotHaveTheSameNumberOfArguments() {
assertThatThrownBy(() -> elasticsearchConverter.get().getMappingContext()
.getRequiredPersistentEntity(SettingsInvalidSortParameterSizes.class).getDefaultSettings())
- .isInstanceOf(IllegalArgumentException.class);
+ .isInstanceOf(IllegalArgumentException.class);
}
@Test // #1719, #2158
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java
index e723143cf9..ac5fab3bd6 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java
@@ -25,6 +25,7 @@
import java.util.GregorianCalendar;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
@@ -44,7 +45,6 @@
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy;
import org.springframework.data.util.TypeInformation;
-import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/paginating/ReactiveSearchAfterIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/paginating/ReactiveSearchAfterIntegrationTests.java
index 62951e4c7c..fc75eacc93 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/paginating/ReactiveSearchAfterIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/paginating/ReactiveSearchAfterIntegrationTests.java
@@ -26,6 +26,7 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -43,7 +44,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/paginating/SearchAfterIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/paginating/SearchAfterIntegrationTests.java
index 674a031624..89d3503856 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/paginating/SearchAfterIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/paginating/SearchAfterIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -41,7 +42,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/paginating/package-info.java b/src/test/java/org/springframework/data/elasticsearch/core/paginating/package-info.java
index d242ad3372..d82a51c47d 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/paginating/package-info.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/paginating/package-info.java
@@ -1,6 +1,5 @@
/**
* Test for paginating support with search_after and point_in_time API
*/
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.core.paginating;
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryIntegrationTests.java
index 2d91462e12..24acedc9db 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryIntegrationTests.java
@@ -20,10 +20,10 @@
import static org.springframework.data.elasticsearch.utils.IdGenerator.*;
import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;
-import java.lang.Long;
import java.util.ArrayList;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -38,7 +38,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
@@ -762,12 +761,11 @@ public void setRate(int rate) {
this.rate = rate;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/NativeQueryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/NativeQueryIntegrationTests.java
index 30a29af122..21f613f16b 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/NativeQueryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/NativeQueryIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/ElasticsearchPartQueryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/RepositoryPartQueryIntegrationTests.java
similarity index 85%
rename from src/test/java/org/springframework/data/elasticsearch/core/query/ElasticsearchPartQueryIntegrationTests.java
rename to src/test/java/org/springframework/data/elasticsearch/core/query/RepositoryPartQueryIntegrationTests.java
index d8501cb522..617ea0ef35 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/ElasticsearchPartQueryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/RepositoryPartQueryIntegrationTests.java
@@ -15,6 +15,7 @@
*/
package org.springframework.data.elasticsearch.core.query;
+import static org.assertj.core.api.Assertions.*;
import static org.skyscreamer.jsonassert.JSONAssert.*;
import java.lang.reflect.Method;
@@ -23,23 +24,25 @@
import java.util.List;
import org.json.JSONException;
+import org.junit.jupiter.api.DisplayName;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
+import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
-import org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery;
import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod;
+import org.springframework.data.elasticsearch.repository.query.RepositoryPartQuery;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.lang.Nullable;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
- * Tests for {@link ElasticsearchPartQuery}. The tests make sure that queries are built according to the method naming.
+ * Tests for {@link RepositoryPartQuery}. The tests make sure that queries are built according to the method naming.
* Classes implementing this abstract class are in the packages of their request factories and converters as these are
* kept package private.
*
@@ -48,7 +51,7 @@
*/
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@SpringIntegrationTest
-public abstract class ElasticsearchPartQueryIntegrationTests {
+public abstract class RepositoryPartQueryIntegrationTests {
public static final String BOOK_TITLE = "Title";
public static final int BOOK_PRICE = 42;
@@ -639,6 +642,84 @@ void findByAvailableTrueOrderByNameDesc() throws NoSuchMethodException, JSONExce
assertEquals(expected, query, false);
}
+ @Test // #3072
+ @DisplayName("should build sort object with correct field names")
+ void shouldBuildSortObjectWithCorrectFieldNames() throws NoSuchMethodException, JSONException {
+
+ String methodName = "findByNameOrderBySortAuthor_SortName";
+ Class>[] parameterClasses = new Class[] { String.class };
+ Object[] parameters = new Object[] { BOOK_TITLE };
+
+ String query = getQueryString(methodName, parameterClasses, parameters);
+
+ String expected = """
+
+ {
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "query_string": {
+ "query": "Title",
+ "fields": [
+ "name"
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "sort": [
+ {
+ "sort_author.sort_name": {
+ "order": "asc"
+ }
+ }
+ ]
+ }""";
+
+ assertEquals(expected, query, false);
+ }
+
+ @Test // #3081
+ @DisplayName("should build sort object with unknown field names")
+ void shouldBuildSortObjectWithUnknownFieldNames() throws NoSuchMethodException, JSONException {
+
+ String methodName = "findByName";
+ Class>[] parameterClasses = new Class[] { String.class, Sort.class };
+ Object[] parameters = new Object[] { BOOK_TITLE, Sort.by("sortAuthor.sortName.raw") };
+
+ String query = getQueryString(methodName, parameterClasses, parameters);
+
+ String expected = """
+
+ {
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "query_string": {
+ "query": "Title",
+ "fields": [
+ "name"
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "sort": [
+ {
+ "sort_author.sort_name.raw": {
+ "order": "asc"
+ }
+ }
+ ]
+ }""";
+
+ assertEquals(expected, query, false);
+ }
+
private String getQueryString(String methodName, Class>[] parameterClasses, Object[] parameters)
throws NoSuchMethodException {
@@ -646,8 +727,8 @@ private String getQueryString(String methodName, Class>[] parameterClasses, Ob
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method,
new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(),
operations.getElasticsearchConverter().getMappingContext());
- ElasticsearchPartQuery partQuery = new ElasticsearchPartQuery(queryMethod, operations,
- QueryMethodEvaluationContextProvider.DEFAULT);
+ RepositoryPartQuery partQuery = new RepositoryPartQuery(queryMethod, operations,
+ ValueExpressionDelegate.create());
Query query = partQuery.createQuery(parameters);
return buildQueryString(query, Book.class);
}
@@ -726,6 +807,9 @@ private interface SampleRepository extends ElasticsearchRepository
List findByAvailableTrueOrderByNameDesc();
+ List findByNameOrderBySortAuthor_SortName(String name);
+
+ List findByName(String name, Sort sort);
}
public static class Book {
@@ -735,6 +819,10 @@ public static class Book {
@Nullable private Integer price;
@Field(type = FieldType.Boolean) private boolean available;
+ // this is needed for the #3072 test
+ @Nullable
+ @Field(name = "sort_author", type = FieldType.Object) private Author sortAuthor;
+
@Nullable
public String getId() {
return id;
@@ -766,8 +854,32 @@ public Boolean getAvailable() {
return available;
}
+ @Nullable
+ public Author getSortAuthor() {
+ return sortAuthor;
+ }
+
+ public void setSortAuthor(@Nullable Author sortAuthor) {
+ this.sortAuthor = sortAuthor;
+ }
+
public void setAvailable(Boolean available) {
this.available = available;
+
+ }
+ }
+
+ public static class Author {
+ @Nullable
+ @Field(name = "sort_name", type = FieldType.Keyword) private String sortName;
+
+ @Nullable
+ public String getSortName() {
+ return sortName;
+ }
+
+ public void setSortName(@Nullable String sortName) {
+ this.sortName = sortName;
}
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ReactiveScriptedAndRuntimeFieldsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ReactiveScriptedAndRuntimeFieldsIntegrationTests.java
index b093d12464..c17b4a8dfe 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ReactiveScriptedAndRuntimeFieldsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ReactiveScriptedAndRuntimeFieldsIntegrationTests.java
@@ -25,6 +25,7 @@
import java.util.Map;
import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -47,11 +48,9 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RuntimeField;
import org.springframework.data.elasticsearch.core.query.ScriptData;
-import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
@@ -165,7 +164,6 @@ private static org.springframework.data.elasticsearch.core.query.ScriptedField g
return org.springframework.data.elasticsearch.core.query.ScriptedField.of(
fieldName,
ScriptData.of(b -> b
- .withType(ScriptType.INLINE)
.withScript("doc['value'].size() > 0 ? doc['value'].value * params['factor'] : 0")
.withParams(Map.of("factor", factor))));
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ScriptedAndRuntimeFieldsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ScriptedAndRuntimeFieldsIntegrationTests.java
index 9d05a240c3..d4b147d469 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ScriptedAndRuntimeFieldsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/scriptedandruntimefields/ScriptedAndRuntimeFieldsIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.Map;
import org.jetbrains.annotations.NotNull;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -44,11 +45,9 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.RuntimeField;
import org.springframework.data.elasticsearch.core.query.ScriptData;
-import org.springframework.data.elasticsearch.core.query.ScriptType;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
@@ -99,6 +98,8 @@ void shouldUseRuntimeFieldFromQueryInSearch() {
@DisplayName("should use runtime-field without script")
void shouldUseRuntimeFieldWithoutScript() {
+ // a runtime field without a script can be used to redefine the type of a field for the search,
+ // here we change the type from text to double
insert("1", "11", 10);
Query query = new CriteriaQuery(new Criteria("description").matches(11.0));
RuntimeField runtimeField = new RuntimeField("description", "double");
@@ -133,6 +134,25 @@ void shouldReturnValueFromRuntimeFieldDefinedInMapping() {
assertThat(foundPerson.getBirthDate()).isEqualTo(birthDate);
}
+ @Test // #3076
+ @DisplayName("should return scripted fields that are lists")
+ void shouldReturnScriptedFieldsThatAreLists() {
+ var person = new Person();
+ person.setFirstName("John");
+ person.setLastName("Doe");
+ operations.save(person);
+ var query = Query.findAll();
+ query.addFields("allNames");
+ query.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("*").build());
+
+ var searchHits = operations.search(query, Person.class);
+
+ assertThat(searchHits.getTotalHits()).isEqualTo(1);
+ var foundPerson = searchHits.getSearchHit(0).getContent();
+ // the painless script seems to return the data sorted no matter in which order the values are emitted
+ assertThat(foundPerson.getAllNames()).containsExactlyInAnyOrderElementsOf(List.of("John", "Doe"));
+ }
+
@Test // #2035
@DisplayName("should use repository method with ScriptedField parameters")
void shouldUseRepositoryMethodWithScriptedFieldParameters() {
@@ -143,9 +163,11 @@ void shouldUseRepositoryMethodWithScriptedFieldParameters() {
repository.save(entity);
- org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1 = getScriptedField("scriptedValue1",
+ org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1 = buildScriptedField(
+ "scriptedValue1",
2);
- org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2 = getScriptedField("scriptedValue2",
+ org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2 = buildScriptedField(
+ "scriptedValue2",
3);
var searchHits = repository.findByValue(3, scriptedField1, scriptedField2);
@@ -157,17 +179,6 @@ void shouldUseRepositoryMethodWithScriptedFieldParameters() {
assertThat(foundEntity.getScriptedValue2()).isEqualTo(9);
}
- @NotNull
- private static org.springframework.data.elasticsearch.core.query.ScriptedField getScriptedField(String fieldName,
- int factor) {
- return org.springframework.data.elasticsearch.core.query.ScriptedField.of(
- fieldName,
- ScriptData.of(b -> b
- .withType(ScriptType.INLINE)
- .withScript("doc['value'].size() > 0 ? doc['value'].value * params['factor'] : 0")
- .withParams(Map.of("factor", factor))));
- }
-
@Test // #2035
@DisplayName("should use repository string query method with ScriptedField parameters")
void shouldUseRepositoryStringQueryMethodWithScriptedFieldParameters() {
@@ -178,9 +189,11 @@ void shouldUseRepositoryStringQueryMethodWithScriptedFieldParameters() {
repository.save(entity);
- org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1 = getScriptedField("scriptedValue1",
+ org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField1 = buildScriptedField(
+ "scriptedValue1",
2);
- org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2 = getScriptedField("scriptedValue2",
+ org.springframework.data.elasticsearch.core.query.ScriptedField scriptedField2 = buildScriptedField(
+ "scriptedValue2",
3);
var searchHits = repository.findWithScriptedFields(3, scriptedField1, scriptedField2);
@@ -202,8 +215,8 @@ void shouldUseRepositoryMethodWithRuntimeFieldParameters() {
repository.save(entity);
- var runtimeField1 = getRuntimeField("scriptedValue1", 3);
- var runtimeField2 = getRuntimeField("scriptedValue2", 4);
+ var runtimeField1 = buildRuntimeField("scriptedValue1", 3);
+ var runtimeField2 = buildRuntimeField("scriptedValue2", 4);
var searchHits = repository.findByValue(3, runtimeField1, runtimeField2);
@@ -214,14 +227,6 @@ void shouldUseRepositoryMethodWithRuntimeFieldParameters() {
assertThat(foundEntity.getScriptedValue2()).isEqualTo(12);
}
- @NotNull
- private static RuntimeField getRuntimeField(String fieldName, int factor) {
- return new RuntimeField(
- fieldName,
- "long",
- String.format("emit(doc['value'].size() > 0 ? doc['value'].value * %d : 0)", factor));
- }
-
@Test // #2035
@DisplayName("should use repository string query method with RuntimeField parameters")
void shouldUseRepositoryStringQueryMethodWithRuntimeFieldParameters() {
@@ -232,8 +237,8 @@ void shouldUseRepositoryStringQueryMethodWithRuntimeFieldParameters() {
repository.save(entity);
- var runtimeField1 = getRuntimeField("scriptedValue1", 3);
- var runtimeField2 = getRuntimeField("scriptedValue2", 4);
+ var runtimeField1 = buildRuntimeField("scriptedValue1", 3);
+ var runtimeField2 = buildRuntimeField("scriptedValue2", 4);
var searchHits = repository.findWithRuntimeFields(3, runtimeField1, runtimeField2);
@@ -263,8 +268,7 @@ void shouldUseParametersForRuntimeFieldsInSearchQueries() {
"priceWithTax",
"double",
"emit(doc['price'].value * params.tax)",
- Map.of("tax", 1.19)
- );
+ Map.of("tax", 1.19));
var query = CriteriaQuery.builder(
Criteria.where("priceWithTax").greaterThan(100.0))
.withRuntimeFields(List.of(runtimeField))
@@ -275,6 +279,55 @@ void shouldUseParametersForRuntimeFieldsInSearchQueries() {
assertThat(searchHits).hasSize(1);
}
+ @Test // #3076
+ @DisplayName("should use runtime fields in queries returning lists")
+ void shouldUseRuntimeFieldsInQueriesReturningLists() {
+
+ insert("1", "item 1", 80.0);
+
+ var runtimeField = new RuntimeField(
+ "someStrings",
+ "keyword",
+ "emit('foo'); emit('bar');",
+ null);
+
+ var query = Query.findAll();
+ query.addRuntimeField(runtimeField);
+ query.addFields("someStrings");
+ query.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("*").build());
+
+ var searchHits = operations.search(query, SomethingToBuy.class);
+
+ assertThat(searchHits).hasSize(1);
+ var somethingToBuy = searchHits.getSearchHit(0).getContent();
+ assertThat(somethingToBuy.someStrings).containsExactlyInAnyOrder("foo", "bar");
+ }
+
+ /**
+ * build a {@link org.springframework.data.elasticsearch.core.query.ScriptedField} to return the product of the
+ * document's value property and the given factor
+ */
+ @NotNull
+ private static org.springframework.data.elasticsearch.core.query.ScriptedField buildScriptedField(String fieldName,
+ int factor) {
+ return org.springframework.data.elasticsearch.core.query.ScriptedField.of(
+ fieldName,
+ ScriptData.of(b -> b
+ .withScript("doc['value'].size() > 0 ? doc['value'].value * params['factor'] : 0")
+ .withParams(Map.of("factor", factor))));
+ }
+
+ /**
+ * build a {@link RuntimeField} to return the product of the document's value property and the given factor
+ */
+ @NotNull
+ private static RuntimeField buildRuntimeField(String fieldName, int factor) {
+ return new RuntimeField(
+ fieldName,
+ "long",
+ String.format("emit(doc['value'].size() > 0 ? doc['value'].value * %d : 0)", factor));
+ }
+
@SuppressWarnings("unused")
@Document(indexName = "#{@indexNameProvider.indexName()}-something-to-by")
private static class SomethingToBuy {
@@ -286,6 +339,9 @@ private static class SomethingToBuy {
@Nullable
@Field(type = FieldType.Double) private Double price;
+ @Nullable
+ @ScriptedField private List someStrings;
+
@Nullable
public String getId() {
return id;
@@ -312,6 +368,15 @@ public Double getPrice() {
public void setPrice(@Nullable Double price) {
this.price = price;
}
+
+ @Nullable
+ public List getSomeStrings() {
+ return someStrings;
+ }
+
+ public void setSomeStrings(@Nullable List someStrings) {
+ this.someStrings = someStrings;
+ }
}
@SuppressWarnings("unused")
@@ -320,6 +385,13 @@ public void setPrice(@Nullable Double price) {
public static class Person {
@Nullable private String id;
+ // need keywords as we are using them in the script
+ @Nullable
+ @Field(type = FieldType.Keyword) private String firstName;
+ @Nullable
+ @Field(type = FieldType.Keyword) private String lastName;
+ @ScriptedField private List allNames = List.of();
+
@Field(type = FieldType.Date, format = DateFormat.basic_date)
@Nullable private LocalDate birthDate;
@@ -335,6 +407,24 @@ public void setId(@Nullable String id) {
this.id = id;
}
+ @Nullable
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(@Nullable String firstName) {
+ this.firstName = firstName;
+ }
+
+ @Nullable
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(@Nullable String lastName) {
+ this.lastName = lastName;
+ }
+
@Nullable
public LocalDate getBirthDate() {
return birthDate;
@@ -352,6 +442,14 @@ public Integer getAge() {
public void setAge(@Nullable Integer age) {
this.age = age;
}
+
+ public List getAllNames() {
+ return allNames;
+ }
+
+ public void setAllNames(List allNames) {
+ this.allNames = allNames;
+ }
}
@SuppressWarnings("unused")
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/sort/NestedSortIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/sort/NestedSortIntegrationTests.java
index 513923554f..f6ee3aaa4f 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/query/sort/NestedSortIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/query/sort/NestedSortIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.function.Function;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Integration tests for nested sorts.
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolverUnitTest.java b/src/test/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolverUnitTest.java
index 5ad256b039..349f8a3f45 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolverUnitTest.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/routing/DefaultRoutingResolverUnitTest.java
@@ -17,6 +17,7 @@
import static org.assertj.core.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -29,7 +30,6 @@
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Routing;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
@@ -40,7 +40,7 @@ class DefaultRoutingResolverUnitTest {
@Autowired private ApplicationContext applicationContext;
- @Nullable private RoutingResolver routingResolver;
+ @Nullable private RoutingResolver routingResolver;
@Configuration
static class Config {
@@ -52,7 +52,7 @@ SpelRouting spelRouting() {
@BeforeEach
void setUp() {
- SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
+ SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
mappingContext.setApplicationContext(applicationContext);
routingResolver = new DefaultRoutingResolver(mappingContext);
@@ -92,7 +92,8 @@ void shouldReturnRoutingFromSpElExpression() {
@Document(indexName = "routing-resolver-test")
@Routing("theRouting")
static class ValidRoutingEntity {
- @Nullable @Id private String id;
+ @Nullable
+ @Id private String id;
@Nullable private String theRouting;
public ValidRoutingEntity(@Nullable String id, @Nullable String theRouting) {
@@ -122,7 +123,8 @@ public void setTheRouting(@Nullable String theRouting) {
@Document(indexName = "routing-resolver-test")
@Routing(value = "@spelRouting.getRouting(#entity)")
static class ValidSpelRoutingEntity {
- @Nullable @Id private String id;
+ @Nullable
+ @Id private String id;
@Nullable private String theRouting;
public ValidSpelRoutingEntity(@Nullable String id, @Nullable String theRouting) {
@@ -152,7 +154,8 @@ public void setTheRouting(@Nullable String theRouting) {
@Document(indexName = "routing-resolver-test")
@Routing("unknownProperty")
static class InvalidRoutingEntity {
- @Nullable @Id private String id;
+ @Nullable
+ @Id private String id;
@Nullable private String theRouting;
public InvalidRoutingEntity(@Nullable String id, @Nullable String theRouting) {
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/routing/ReactiveRoutingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/routing/ReactiveRoutingTests.java
index 95345858a8..f80111f8db 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/routing/ReactiveRoutingTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/routing/ReactiveRoutingTests.java
@@ -21,6 +21,7 @@
import java.util.Objects;
import java.util.function.Function;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/routing/RoutingIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/routing/RoutingIntegrationTests.java
index ddbc4949a2..901af03ca7 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/routing/RoutingIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/routing/RoutingIntegrationTests.java
@@ -25,6 +25,7 @@
import org.apache.commons.codec.digest.MurmurHash3;
import org.assertj.core.api.SoftAssertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -45,7 +46,6 @@
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/sql/ReactiveSqlOperationsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/sql/ReactiveSqlOperationsIntegrationTests.java
index 8d6ddcc4fb..a47eba4da0 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/sql/ReactiveSqlOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/sql/ReactiveSqlOperationsIntegrationTests.java
@@ -21,6 +21,7 @@
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -34,7 +35,6 @@
import org.springframework.data.elasticsearch.core.query.SqlQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/sql/SqlOperationsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/sql/SqlOperationsIntegrationTests.java
index 6e3ce29c9c..b62cc7ee4b 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/sql/SqlOperationsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/sql/SqlOperationsIntegrationTests.java
@@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -32,7 +33,6 @@
import org.springframework.data.elasticsearch.core.query.SqlQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionIntegrationTests.java
index fc52f8c5bf..e167a8314e 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionWithContextsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionWithContextsIntegrationTests.java
index 148b7183bc..24e495af43 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionWithContextsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/suggest/CompletionWithContextsIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Robert Gruendler
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/suggest/ReactiveSuggestIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/suggest/ReactiveSuggestIntegrationTests.java
index 8a629516ce..69f4fc8a4e 100644
--- a/src/test/java/org/springframework/data/elasticsearch/core/suggest/ReactiveSuggestIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/core/suggest/ReactiveSuggestIntegrationTests.java
@@ -24,6 +24,7 @@
import java.util.Arrays;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -40,7 +41,6 @@
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableRepositoryIntegrationTests.java
index a6407d15ee..1236b88971 100644
--- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableRepositoryIntegrationTests.java
@@ -19,6 +19,7 @@
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -30,7 +31,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.repository.CrudRepository;
-import org.springframework.lang.Nullable;
/**
* @author Young Gu
diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java
index 2b2a6bf1e8..30112fa260 100644
--- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java
+++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java
@@ -26,10 +26,10 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.lang.Nullable;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.utility.DockerImageName;
@@ -129,6 +129,9 @@ private ClusterConnectionInfo startElasticsearchContainer() {
Map testcontainersProperties = testcontainersProperties(
"testcontainers-" + testcontainersConfiguration + ".properties");
+ var testcontainersPropertiesLocal = testcontainersProperties("testcontainers-local.properties");
+ testcontainersProperties.putAll(testcontainersPropertiesLocal);
+
DockerImageName dockerImageName = getDockerImageName(testcontainersProperties);
ElasticsearchContainer elasticsearchContainer = new SpringDataElasticsearchContainer(dockerImageName)
@@ -192,7 +195,6 @@ private Map testcontainersProperties(String propertiesFile) {
@Override
public void close() {
-
}
private static class SpringDataElasticsearchContainer extends ElasticsearchContainer {
diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java
index 76c837783f..1a3266a9f9 100644
--- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java
+++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java
@@ -15,7 +15,7 @@
*/
package org.springframework.data.elasticsearch.junit.jupiter;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/package-info.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/package-info.java
index e6e7542679..bf18bbf1eb 100644
--- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/package-info.java
+++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/package-info.java
@@ -1,5 +1,5 @@
/**
* interfaces, annotations and classes related to JUnit 5 test handling.
*/
-@org.springframework.lang.NonNullApi
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.junit.jupiter;
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java
index e6b5536b22..ad7f72ec1a 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java
@@ -17,7 +17,7 @@
import jakarta.inject.Inject;
-import org.springframework.lang.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* @author Mohsin Husen
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java
index a0b7cab669..f0236249f9 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java
@@ -17,6 +17,9 @@
import static org.assertj.core.api.Assertions.*;
+import jakarta.enterprise.inject.se.SeContainer;
+import jakarta.enterprise.inject.se.SeContainerInitializer;
+
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
@@ -24,9 +27,7 @@
import java.util.Map;
import java.util.Optional;
-import jakarta.enterprise.inject.se.SeContainer;
-import jakarta.enterprise.inject.se.SeContainerInitializer;
-
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -40,7 +41,6 @@
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.IntegrationTest;
-import org.springframework.lang.Nullable;
/**
* @author Mohsin Husen
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java
index 00c6f2bb9a..065343171d 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java
@@ -1,3 +1,2 @@
-@org.springframework.lang.NonNullApi
-@org.springframework.lang.NonNullFields
+@org.jspecify.annotations.NullMarked
package org.springframework.data.elasticsearch.repositories.cdi;
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryIntegrationTests.java
index 856efdf0ae..435c018c83 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryIntegrationTests.java
@@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -29,7 +30,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Artur Konczak
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringIntegrationTests.java
index 5f5490b495..4f74e728a4 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringIntegrationTests.java
@@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -29,7 +30,6 @@
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Artur Konczak
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryIntegrationTests.java
index 1b19b0cbeb..bdbc8b7750 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryIntegrationTests.java
@@ -29,6 +29,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -66,7 +67,6 @@
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.repository.query.Param;
-import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -2534,12 +2534,11 @@ public void setLocation(@Nullable GeoPoint location) {
this.location = location;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/GeoRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/GeoRepositoryIntegrationTests.java
index 4ab4918638..c876044d8a 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/GeoRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/GeoRepositoryIntegrationTests.java
@@ -20,6 +20,7 @@
import java.util.Locale;
import java.util.Optional;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -38,7 +39,6 @@
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
-import org.springframework.lang.Nullable;
/**
* @author Mark Paluch
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/knn/KnnSearchIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/knn/KnnSearchIntegrationTests.java
index 2c7027c348..12af3eccee 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/knn/KnnSearchIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/knn/KnnSearchIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.UUID;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,7 +44,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Haibo Liu
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectIntegrationTests.java
index 90f3a2a108..8c744e28fe 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectIntegrationTests.java
@@ -23,6 +23,7 @@
import java.util.HashMap;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -38,7 +39,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Mohsin Husen
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryIntegrationTests.java
index ea418a2be2..d28685a162 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryIntegrationTests.java
@@ -17,6 +17,7 @@
import static org.assertj.core.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -34,7 +35,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* SynonymRepositoryIntegrationTests
diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryIntegrationTests.java
index 00dae64e25..cb279b7ee3 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryIntegrationTests.java
@@ -24,6 +24,7 @@
import java.util.Optional;
import java.util.UUID;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,13 +39,11 @@
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.ScriptedField;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
-import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Gad Akuka
@@ -61,12 +60,12 @@ public abstract class UUIDElasticsearchRepositoryIntegrationTests {
@Autowired private SampleUUIDKeyedElasticsearchRepository repository;
@Autowired ElasticsearchOperations operations;
- @Autowired IndexNameProvider indexNameProvider;
+ @Autowired IndexNameProvider indexNameProvider;
@BeforeEach
public void before() {
indexNameProvider.increment();
- operations.indexOps(SampleEntityUUIDKeyed.class).createWithMapping();
+ operations.indexOps(SampleEntityUUIDKeyed.class).createWithMapping();
}
@Test
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java
index 79b43c3e6a..67066c2204 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java
@@ -18,6 +18,7 @@
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import org.assertj.core.api.Assertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -30,7 +31,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
/**
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethodUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethodUnitTests.java
index abf2f41579..00ec7a663c 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethodUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethodUnitTests.java
@@ -20,6 +20,7 @@
import java.lang.reflect.Method;
import java.util.List;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -32,7 +33,6 @@
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTestBase.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTestBase.java
deleted file mode 100644
index ef0f79cb73..0000000000
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTestBase.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2021-2025 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.ArrayList;
-import java.util.Collection;
-
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.data.convert.CustomConversions;
-import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
-import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
-import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
-import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
-import org.springframework.lang.Nullable;
-
-/**
- * @author Peter-Josef Meisch
- */
-public class ElasticsearchStringQueryUnitTestBase {
-
- protected ElasticsearchConverter setupConverter() {
- MappingElasticsearchConverter converter = new MappingElasticsearchConverter(
- new SimpleElasticsearchMappingContext());
- Collection> converters = new ArrayList<>();
- converters.add(ElasticsearchStringQueryUnitTests.CarConverter.INSTANCE);
- CustomConversions customConversions = new ElasticsearchCustomConversions(converters);
- converter.setConversions(customConversions);
- converter.afterPropertiesSet();
- return converter;
- }
-
- static class Car {
- @Nullable private String name;
- @Nullable private String model;
-
- @Nullable
- public String getName() {
- return name;
- }
-
- public void setName(@Nullable String name) {
- this.name = name;
- }
-
- @Nullable
- public String getModel() {
- return model;
- }
-
- public void setModel(@Nullable String model) {
- this.model = model;
- }
- }
-
- enum CarConverter implements Converter {
- INSTANCE;
-
- @Override
- public String convert(ElasticsearchStringQueryUnitTests.Car car) {
- return (car.getName() != null ? car.getName() : "null") + '-'
- + (car.getModel() != null ? car.getModel() : "null");
- }
- }
-
-}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java
index 84adf695db..460ede8666 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java
@@ -26,6 +26,7 @@
import java.util.List;
import java.util.Map;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -45,7 +46,6 @@
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
-import org.springframework.lang.Nullable;
/**
* @author Christoph Strobl
@@ -77,7 +77,7 @@ public void rejectsNullMappingContext() throws Exception {
assertThatThrownBy(() -> new ReactiveElasticsearchQueryMethod(method,
new DefaultRepositoryMetadata(PersonRepository.class), new SpelAwareProxyProjectionFactory(), null))
- .isInstanceOf(IllegalArgumentException.class);
+ .isInstanceOf(IllegalArgumentException.class);
}
@Test // DATAES-519
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryQueryUnitTestsBase.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryQueryUnitTestsBase.java
new file mode 100644
index 0000000000..4ab8196324
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryQueryUnitTestsBase.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2025 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 static org.mockito.Mockito.*;
+
+import java.lang.reflect.Method;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
+import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
+import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
+import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
+import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
+
+@ExtendWith(MockitoExtension.class)
+public class ReactiveRepositoryQueryUnitTestsBase {
+
+ @Mock ReactiveElasticsearchOperations operations;
+
+ /**
+ * set up the {operations} mock to return the {@link ElasticsearchConverter} from setupConverter().
+ */
+ @BeforeEach
+ public void setUp() {
+ when(operations.getElasticsearchConverter()).thenReturn(setupConverter());
+ }
+
+ /**
+ * @return a simple {@link MappingElasticsearchConverter} with no special setup.
+ */
+ protected MappingElasticsearchConverter setupConverter() {
+ return new MappingElasticsearchConverter(
+ new SimpleElasticsearchMappingContext());
+ }
+
+ /**
+ * Creates a {@link ReactiveElasticsearchQueryMethod} for the given method
+ *
+ * @param repositoryClass
+ * @param name
+ * @param parameters
+ * @return
+ * @throws NoSuchMethodException
+ */
+
+ protected ReactiveElasticsearchQueryMethod getQueryMethod(Class> repositoryClass, String name,
+ Class>... parameters)
+ throws NoSuchMethodException {
+
+ Method method = repositoryClass.getMethod(name, parameters);
+ return new ReactiveElasticsearchQueryMethod(method,
+ new DefaultRepositoryMetadata(repositoryClass),
+ new SpelAwareProxyProjectionFactory(), operations.getElasticsearchConverter().getMappingContext());
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQueryUnitTests.java
new file mode 100644
index 0000000000..9e6e89c19e
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositorySearchTemplateQueryUnitTests.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2025 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 static org.assertj.core.api.Assertions.*;
+
+import java.util.Arrays;
+
+import org.jspecify.annotations.Nullable;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.SearchTemplateQuery;
+import org.springframework.data.elasticsearch.core.SearchHits;
+import org.springframework.data.elasticsearch.core.query.Query;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+
+public class ReactiveRepositorySearchTemplateQueryUnitTests extends ReactiveRepositoryQueryUnitTestsBase {
+
+ @Test // #2997
+ @DisplayName("should set searchtemplate id")
+ void shouldSetSearchTemplateId() throws NoSuchMethodException {
+
+ var query = createQuery("searchWithArgs", "answer", 42);
+
+ assertThat(query).isInstanceOf(org.springframework.data.elasticsearch.core.query.SearchTemplateQuery.class);
+ var searchTemplateQuery = (org.springframework.data.elasticsearch.core.query.SearchTemplateQuery) query;
+
+ assertThat(searchTemplateQuery.getId()).isEqualTo("searchtemplate-42");
+ }
+
+ @Test // #2997
+ @DisplayName("should set searchtemplate parameters")
+ void shouldSetSearchTemplateParameters() throws NoSuchMethodException {
+
+ var query = createQuery("searchWithArgs", "answer", 42);
+
+ assertThat(query).isInstanceOf(org.springframework.data.elasticsearch.core.query.SearchTemplateQuery.class);
+ var searchTemplateQuery = (org.springframework.data.elasticsearch.core.query.SearchTemplateQuery) query;
+
+ var params = searchTemplateQuery.getParams();
+ assertThat(params).isNotNull().hasSize(2);
+ assertThat(params.get("stringArg")).isEqualTo("answer");
+ assertThat(params.get("intArg")).isEqualTo(42);
+ }
+
+ // region helper methods
+ private Query createQuery(String methodName, Object... args) throws NoSuchMethodException {
+ Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
+ ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(SampleRepository.class, methodName, argTypes);
+
+ ReactiveRepositorySearchTemplateQuery repositorySearchTemplateQuery = queryForMethod(queryMethod);
+
+ return repositorySearchTemplateQuery.createQuery(new ElasticsearchParametersParameterAccessor(queryMethod, args));
+ }
+
+ private ReactiveRepositorySearchTemplateQuery queryForMethod(ReactiveElasticsearchQueryMethod queryMethod) {
+ return new ReactiveRepositorySearchTemplateQuery(queryMethod, operations, ValueExpressionDelegate.create(),
+ queryMethod.getAnnotatedSearchTemplateQuery().id());
+ }
+ // endregion
+
+ // region test data
+ private interface SampleRepository extends ElasticsearchRepository {
+ @SearchTemplateQuery(id = "searchtemplate-42")
+ SearchHits searchWithArgs(String stringArg, Integer intArg);
+
+ @SearchTemplateQuery(id = "searchtemplate-42")
+ SearchHits searchWithArgsAndSort(String stringArg, Integer intArg, Sort sort);
+ }
+
+ @Document(indexName = "not-relevant")
+ static class SampleEntity {
+ @Nullable
+ @Id String id;
+ @Nullable String data;
+
+ @Nullable
+ public String getId() {
+ return id;
+ }
+
+ public void setId(@Nullable String id) {
+ this.id = id;
+ }
+
+ @Nullable
+ public String getData() {
+ return data;
+ }
+
+ public void setData(@Nullable String data) {
+ this.data = data;
+ }
+ }
+ // endregion
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQueryUnitTests.java
similarity index 89%
rename from src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java
rename to src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQueryUnitTests.java
index e5a9f626dc..c6b93802b7 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveRepositoryStringQueryUnitTests.java
@@ -16,12 +16,10 @@
package org.springframework.data.elasticsearch.repository.query;
import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -29,30 +27,29 @@
import java.util.List;
import java.util.Map;
-import org.junit.jupiter.api.BeforeEach;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.CustomConversions;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.annotations.Query;
-import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
+import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
+import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter;
-import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.lang.Nullable;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
* @author Christoph Strobl
@@ -60,13 +57,54 @@
* @author Haibo Liu
*/
@ExtendWith(MockitoExtension.class)
-public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStringQueryUnitTestBase {
+public class ReactiveRepositoryStringQueryUnitTests extends ReactiveRepositoryQueryUnitTestsBase {
- @Mock ReactiveElasticsearchOperations operations;
+ /**
+ * Adds some data class and custom conversion to the base class implementation.
+ */
+ protected MappingElasticsearchConverter setupConverter() {
+
+ Collection> converters = new ArrayList<>();
+ converters.add(CarConverter.INSTANCE);
+ CustomConversions customConversions = new ElasticsearchCustomConversions(converters);
+
+ MappingElasticsearchConverter converter = super.setupConverter();
+ converter.setConversions(customConversions);
+ converter.afterPropertiesSet();
+ return converter;
+ }
+
+ static class Car {
+ @Nullable private String name;
+ @Nullable private String model;
+
+ @Nullable
+ public String getName() {
+ return name;
+ }
+
+ public void setName(@Nullable String name) {
+ this.name = name;
+ }
+
+ @Nullable
+ public String getModel() {
+ return model;
+ }
- @BeforeEach
- public void setUp() {
- when(operations.getElasticsearchConverter()).thenReturn(setupConverter());
+ public void setModel(@Nullable String model) {
+ this.model = model;
+ }
+ }
+
+ enum CarConverter implements Converter {
+ INSTANCE;
+
+ @Override
+ public String convert(Car car) {
+ return (car.getName() != null ? car.getName() : "null") + '-'
+ + (car.getModel() != null ? car.getModel() : "null");
+ }
}
@Test // DATAES-519
@@ -367,29 +405,21 @@ private org.springframework.data.elasticsearch.core.query.Query createQuery(Stri
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);
- ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
+ ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(SampleRepository.class, methodName, argTypes);
+ ReactiveRepositoryStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
return elasticsearchStringQuery.createQuery(new ElasticsearchParametersParameterAccessor(queryMethod, args));
}
- private ReactiveElasticsearchStringQuery queryForMethod(ReactiveElasticsearchQueryMethod queryMethod) {
- return new ReactiveElasticsearchStringQuery(queryMethod, operations,
- QueryMethodEvaluationContextProvider.DEFAULT);
- }
-
- private ReactiveElasticsearchQueryMethod getQueryMethod(String name, Class>... parameters)
- throws NoSuchMethodException {
+ private ReactiveRepositoryStringQuery createQueryForMethod(String name, Class>... parameters) throws Exception {
- Method method = SampleRepository.class.getMethod(name, parameters);
- return new ReactiveElasticsearchQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class),
- new SpelAwareProxyProjectionFactory(), operations.getElasticsearchConverter().getMappingContext());
+ ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(SampleRepository.class, name, parameters);
+ return queryForMethod(queryMethod);
}
- private ReactiveElasticsearchStringQuery createQueryForMethod(String name, Class>... parameters) throws Exception {
-
- ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(name, parameters);
- return queryForMethod(queryMethod);
+ private ReactiveRepositoryStringQuery queryForMethod(ReactiveElasticsearchQueryMethod queryMethod) {
+ return new ReactiveRepositoryStringQuery(queryMethod, operations,
+ ValueExpressionDelegate.create());
}
private interface SampleRepository extends Repository {
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryQueryUnitTestsBase.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryQueryUnitTestsBase.java
new file mode 100644
index 0000000000..3d80c995af
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryQueryUnitTestsBase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2025 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 static org.mockito.Mockito.*;
+
+import java.lang.reflect.Method;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
+import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
+import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
+import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
+import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
+
+@ExtendWith(MockitoExtension.class)
+public class RepositoryQueryUnitTestsBase {
+
+ @Mock ElasticsearchOperations operations;
+
+ /**
+ * set up the {operations} mock to return the {@link ElasticsearchConverter} from setupConverter().
+ */
+ @BeforeEach
+ public void setUp() {
+ when(operations.getElasticsearchConverter()).thenReturn(setupConverter());
+ }
+
+ /**
+ * @return a simple {@link MappingElasticsearchConverter} with no special setup.
+ */
+ protected MappingElasticsearchConverter setupConverter() {
+ return new MappingElasticsearchConverter(
+ new SimpleElasticsearchMappingContext());
+ }
+
+ /**
+ * Creates a {@link ElasticsearchQueryMethod} for the given method
+ *
+ * @param repositoryClass
+ * @param name
+ * @param parameters
+ * @return
+ * @throws NoSuchMethodException
+ */
+ protected ElasticsearchQueryMethod getQueryMethod(Class> repositoryClass, String name, Class>... parameters)
+ throws NoSuchMethodException {
+
+ Method method = repositoryClass.getMethod(name, parameters);
+ return new ElasticsearchQueryMethod(method, new DefaultRepositoryMetadata(repositoryClass),
+ new SpelAwareProxyProjectionFactory(), operations.getElasticsearchConverter().getMappingContext());
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQueryUnitTests.java
new file mode 100644
index 0000000000..6f0d996cf2
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositorySearchTemplateQueryUnitTests.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2025 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 static org.assertj.core.api.Assertions.*;
+
+import java.util.Arrays;
+
+import org.jspecify.annotations.Nullable;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.SearchTemplateQuery;
+import org.springframework.data.elasticsearch.core.SearchHits;
+import org.springframework.data.elasticsearch.core.query.Query;
+import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
+
+public class RepositorySearchTemplateQueryUnitTests extends RepositoryQueryUnitTestsBase {
+
+ @Test // #2997
+ @DisplayName("should set searchtemplate id")
+ void shouldSetSearchTemplateId() throws NoSuchMethodException {
+
+ var query = createQuery("searchWithArgs", "answer", 42);
+
+ assertThat(query).isInstanceOf(org.springframework.data.elasticsearch.core.query.SearchTemplateQuery.class);
+ var searchTemplateQuery = (org.springframework.data.elasticsearch.core.query.SearchTemplateQuery) query;
+
+ assertThat(searchTemplateQuery.getId()).isEqualTo("searchtemplate-42");
+ }
+
+ @Test // #2997
+ @DisplayName("should set searchtemplate parameters")
+ void shouldSetSearchTemplateParameters() throws NoSuchMethodException {
+
+ var query = createQuery("searchWithArgs", "answer", 42);
+
+ assertThat(query).isInstanceOf(org.springframework.data.elasticsearch.core.query.SearchTemplateQuery.class);
+ var searchTemplateQuery = (org.springframework.data.elasticsearch.core.query.SearchTemplateQuery) query;
+
+ var params = searchTemplateQuery.getParams();
+ assertThat(params).isNotNull().hasSize(2);
+ assertThat(params.get("stringArg")).isEqualTo("answer");
+ assertThat(params.get("intArg")).isEqualTo(42);
+ }
+
+ // region helper methods
+ private Query createQuery(String methodName, Object... args) throws NoSuchMethodException {
+ Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
+ ElasticsearchQueryMethod queryMethod = getQueryMethod(SampleRepository.class, methodName, argTypes);
+
+ RepositorySearchTemplateQuery repositorySearchTemplateQuery = queryForMethod(queryMethod);
+
+ return repositorySearchTemplateQuery.createQuery(new ElasticsearchParametersParameterAccessor(queryMethod, args));
+ }
+
+ private RepositorySearchTemplateQuery queryForMethod(ElasticsearchQueryMethod queryMethod) {
+ return new RepositorySearchTemplateQuery(queryMethod, operations, ValueExpressionDelegate.create(),
+ queryMethod.getAnnotatedSearchTemplateQuery().id());
+ }
+ // endregion
+
+ // region test data
+ private interface SampleRepository extends ElasticsearchRepository {
+ @SearchTemplateQuery(id = "searchtemplate-42")
+ SearchHits searchWithArgs(String stringArg, Integer intArg);
+
+ @SearchTemplateQuery(id = "searchtemplate-42")
+ SearchHits searchWithArgsAndSort(String stringArg, Integer intArg, Sort sort);
+ }
+
+ @Document(indexName = "not-relevant")
+ static class SampleEntity {
+ @Nullable
+ @Id String id;
+ @Nullable String data;
+
+ @Nullable
+ public String getId() {
+ return id;
+ }
+
+ public void setId(@Nullable String id) {
+ this.id = id;
+ }
+
+ @Nullable
+ public String getData() {
+ return data;
+ }
+
+ public void setData(@Nullable String data) {
+ this.data = data;
+ }
+ }
+ // endregion
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTests.java
similarity index 88%
rename from src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java
rename to src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTests.java
index c15612ff6b..bb4595e478 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTests.java
@@ -16,9 +16,7 @@
package org.springframework.data.elasticsearch.repository.query;
import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -26,30 +24,27 @@
import java.util.List;
import java.util.Map;
-import org.junit.jupiter.api.BeforeEach;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.CustomConversions;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.annotations.Query;
-import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
+import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
+import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.repositories.custommethod.QueryParameter;
-import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.Repository;
-import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
-import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
-import org.springframework.lang.Nullable;
+import org.springframework.data.repository.query.ValueExpressionDelegate;
/**
* @author Christoph Strobl
@@ -57,14 +52,53 @@
* @author Niklas Herder
* @author Haibo Liu
*/
-@ExtendWith(MockitoExtension.class)
-public class ElasticsearchStringQueryUnitTests extends ElasticsearchStringQueryUnitTestBase {
+public class RepositoryStringQueryUnitTests extends RepositoryStringQueryUnitTestsBase {
+ /**
+ * Adds some data class and custom conversion to the base class implementation.
+ */
+ protected MappingElasticsearchConverter setupConverter() {
+
+ Collection> converters = new ArrayList<>();
+ converters.add(RepositoryStringQueryUnitTests.CarConverter.INSTANCE);
+ CustomConversions customConversions = new ElasticsearchCustomConversions(converters);
+
+ MappingElasticsearchConverter converter = super.setupConverter();
+ converter.setConversions(customConversions);
+ converter.afterPropertiesSet();
+ return converter;
+ }
+
+ static class Car {
+ @Nullable private String name;
+ @Nullable private String model;
+
+ @Nullable
+ public String getName() {
+ return name;
+ }
+
+ public void setName(@Nullable String name) {
+ this.name = name;
+ }
- @Mock ElasticsearchOperations operations;
+ @Nullable
+ public String getModel() {
+ return model;
+ }
- @BeforeEach
- public void setUp() {
- when(operations.getElasticsearchConverter()).thenReturn(setupConverter());
+ public void setModel(@Nullable String model) {
+ this.model = model;
+ }
+ }
+
+ enum CarConverter implements Converter {
+ INSTANCE;
+
+ @Override
+ public String convert(Car car) {
+ return (car.getName() != null ? car.getName() : "null") + '-'
+ + (car.getModel() != null ? car.getModel() : "null");
+ }
}
@Test // DATAES-552
@@ -350,8 +384,9 @@ private org.springframework.data.elasticsearch.core.query.Query createQuery(Stri
throws NoSuchMethodException {
Class>[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
- ElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes);
- ElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
+ ElasticsearchQueryMethod queryMethod = getQueryMethod(RepositoryStringQueryUnitTests.SampleRepository.class,
+ methodName, argTypes);
+ RepositoryStringQuery elasticsearchStringQuery = queryForMethod(queryMethod);
return elasticsearchStringQuery.createQuery(new ElasticsearchParametersParameterAccessor(queryMethod, args));
}
@@ -370,16 +405,9 @@ void shouldUseConverterOnParameters() throws NoSuchMethodException {
.isEqualTo("{ 'bool' : { 'must' : { 'term' : { 'car' : 'Toyota-Prius' } } } }");
}
- private ElasticsearchStringQuery queryForMethod(ElasticsearchQueryMethod queryMethod) {
- return new ElasticsearchStringQuery(queryMethod, operations, queryMethod.getAnnotatedQuery(),
- QueryMethodEvaluationContextProvider.DEFAULT);
- }
-
- private ElasticsearchQueryMethod getQueryMethod(String name, Class>... parameters) throws NoSuchMethodException {
-
- Method method = SampleRepository.class.getMethod(name, parameters);
- return new ElasticsearchQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class),
- new SpelAwareProxyProjectionFactory(), operations.getElasticsearchConverter().getMappingContext());
+ private RepositoryStringQuery queryForMethod(ElasticsearchQueryMethod queryMethod) {
+ return new RepositoryStringQuery(queryMethod, operations, queryMethod.getAnnotatedQuery(),
+ ValueExpressionDelegate.create());
}
private interface SampleRepository extends Repository {
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptType.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTestsBase.java
similarity index 77%
rename from src/main/java/org/springframework/data/elasticsearch/core/query/ScriptType.java
rename to src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTestsBase.java
index 1c6ceecab2..c6ae397433 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/query/ScriptType.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/RepositoryStringQueryUnitTestsBase.java
@@ -13,15 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.data.elasticsearch.core.query;
+package org.springframework.data.elasticsearch.repository.query;
/**
- * Define script types for update queries.
- *
- * @author Farid Faoudi
- * @since 4.2
+ * @author Peter-Josef Meisch
*/
+public class RepositoryStringQueryUnitTestsBase extends RepositoryQueryUnitTestsBase {
-public enum ScriptType {
- INLINE, STORED
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsIntegrationTests.java
index 442d49ea2a..32b92dc691 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsIntegrationTests.java
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -37,7 +38,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* base class for query keyword tests. Implemented by subclasses using ElasticsearchClient and ElasticsearchRestClient
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java
index a2a4c74431..e5d05446d6 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java
@@ -22,6 +22,7 @@
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -36,7 +37,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* @author Peter-Josef Meisch
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ReactiveValueConverterIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ReactiveValueConverterIntegrationTests.java
index 3d8044844d..ad36038f7f 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ReactiveValueConverterIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ReactiveValueConverterIntegrationTests.java
@@ -15,21 +15,10 @@
*/
package org.springframework.data.elasticsearch.repository.query.valueconverter;
-import static org.assertj.core.api.Assertions.*;
-import static org.springframework.data.elasticsearch.annotations.FieldType.*;
-
-import org.springframework.data.elasticsearch.annotations.FieldType;
-import org.springframework.data.elasticsearch.annotations.Query;
-import org.springframework.data.elasticsearch.annotations.ValueConverter;
-import org.springframework.data.elasticsearch.core.SearchHits;
-import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
-import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
-import java.lang.Boolean;
-
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -38,13 +27,16 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
+import org.springframework.data.elasticsearch.annotations.Query;
+import org.springframework.data.elasticsearch.annotations.ValueConverter;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
+import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Integration tests to check that {@link org.springframework.data.elasticsearch.annotations.ValueConverter} annotated
@@ -73,7 +65,6 @@ void cleanup() {
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + '*')).delete().block();
}
-
@Test // #2338
@DisplayName("should apply ValueConverter")
void shouldApplyValueConverter() {
@@ -84,14 +75,14 @@ void shouldApplyValueConverter() {
operations.save(entity).block();
repository.queryByText("text-answer") //
- .as(StepVerifier::create) //
- .expectNextCount(1) //
- .verifyComplete();
+ .as(StepVerifier::create) //
+ .expectNextCount(1) //
+ .verifyComplete();
repository.findByText("answer") //
- .as(StepVerifier::create) //
- .expectNextCount(1) //
- .verifyComplete();
+ .as(StepVerifier::create) //
+ .expectNextCount(1) //
+ .verifyComplete();
}
interface EntityRepository extends ReactiveElasticsearchRepository {
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ValueConverterIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ValueConverterIntegrationTests.java
index 6fdbfc75b3..f4054676db 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ValueConverterIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/valueconverter/ValueConverterIntegrationTests.java
@@ -17,6 +17,7 @@
import static org.assertj.core.api.Assertions.*;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order;
@@ -35,7 +36,6 @@
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
-import org.springframework.lang.Nullable;
/**
* Integration tests to check that {@link org.springframework.data.elasticsearch.annotations.ValueConverter} annotated
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryIntegrationTests.java
index 7c037b8231..d4576de5f8 100644
--- a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryIntegrationTests.java
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryIntegrationTests.java
@@ -28,6 +28,7 @@
import java.util.stream.Collectors;
import org.assertj.core.api.Assertions;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -47,7 +48,6 @@
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.util.StreamUtils;
-import org.springframework.lang.Nullable;
/**
* @author Rizwan Idrees
@@ -712,12 +712,11 @@ public void setAvailable(boolean available) {
this.available = available;
}
- @Nullable
- public java.lang.Long getVersion() {
+ public java.lang.@Nullable Long getVersion() {
return version;
}
- public void setVersion(@Nullable java.lang.Long version) {
+ public void setVersion(java.lang.@Nullable Long version) {
this.version = version;
}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryELCIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryELCIntegrationTests.java
new file mode 100644
index 0000000000..da01834385
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryELCIntegrationTests.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2025 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.support;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
+import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
+import org.springframework.data.elasticsearch.utils.IndexNameProvider;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * @since 5.5
+ */
+@ContextConfiguration(classes = ReactiveRepositoryQueryELCIntegrationTests.Config.class)
+public class ReactiveRepositoryQueryELCIntegrationTests
+ extends ReactiveRepositoryQueryIntegrationTests {
+
+ @Configuration
+ @Import({ ReactiveElasticsearchTemplateConfiguration.class })
+ @EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
+ static class Config {
+ @Bean
+ IndexNameProvider indexNameProvider() {
+ return new IndexNameProvider("reactive-repository-query");
+ }
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryIntegrationTests.java
new file mode 100644
index 0000000000..f5729f3474
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ReactiveRepositoryQueryIntegrationTests.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2025 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.support;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.springframework.data.elasticsearch.core.IndexOperationsAdapter.*;
+
+import reactor.core.publisher.Flux;
+
+import java.util.List;
+
+import org.jspecify.annotations.Nullable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.Document;
+import org.springframework.data.elasticsearch.annotations.Field;
+import org.springframework.data.elasticsearch.annotations.FieldType;
+import org.springframework.data.elasticsearch.annotations.SearchTemplateQuery;
+import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
+import org.springframework.data.elasticsearch.core.SearchHit;
+import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
+import org.springframework.data.elasticsearch.core.script.Script;
+import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
+import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
+import org.springframework.data.elasticsearch.utils.IndexNameProvider;
+
+/**
+ * @since 5.5
+ */
+@SpringIntegrationTest
+abstract class ReactiveRepositoryQueryIntegrationTests {
+ @Autowired private SampleElasticsearchRepository repository;
+ @Autowired private ReactiveElasticsearchOperations operations;
+ @Autowired private IndexNameProvider indexNameProvider;
+
+ @BeforeEach
+ void before() {
+ indexNameProvider.increment();
+ blocking(operations.indexOps(LOTRCharacter.class)).createWithMapping();
+ }
+
+ @Test
+ @org.junit.jupiter.api.Order(Integer.MAX_VALUE)
+ public void cleanup() {
+ blocking(operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*"))).delete();
+ }
+
+ @Test // #2997
+ @DisplayName("should use searchtemplate query")
+ void shouldUseSearchtemplateQuery() {
+ // store some data
+ repository.saveAll(List.of(
+ new LOTRCharacter("1", "Frodo is a hobbit"),
+ new LOTRCharacter("2", "Legolas is an elf"),
+ new LOTRCharacter("3", "Gandalf is a wizard"),
+ new LOTRCharacter("4", "Bilbo is a hobbit"),
+ new LOTRCharacter("5", "Gimli is a dwarf")))
+ .blockLast();
+
+ // store a searchtemplate
+ String searchInCharacter = """
+ {
+ "query": {
+ "bool": {
+ "must": [
+ {
+ "match": {
+ "lotrCharacter": "{{word}}"
+ }
+ }
+ ]
+ }
+ },
+ "from": 0,
+ "size": 100,
+ "sort": {
+ "id": {
+ "order": "desc"
+ }
+ }
+ }
+ """;
+
+ Script scriptSearchInCharacter = Script.builder() //
+ .withId("searchInCharacter") //
+ .withLanguage("mustache") //
+ .withSource(searchInCharacter) //
+ .build();
+
+ var success = operations.putScript(scriptSearchInCharacter).block();
+ assertThat(success).isTrue();
+
+ // search with repository for hobbits order by id descending
+ var searchHits = repository.searchInCharacter("hobbit")
+ .collectList().block();
+
+ // check result (bilbo, frodo)
+ assertThat(searchHits).isNotNull();
+ assertThat(searchHits.size()).isEqualTo(2);
+ assertThat(searchHits.get(0).getId()).isEqualTo("4");
+ assertThat(searchHits.get(1).getId()).isEqualTo("1");
+ }
+
+ @Document(indexName = "#{@indexNameProvider.indexName()}")
+ static class LOTRCharacter {
+ @Nullable
+ @Id
+ @Field(fielddata = true) // needed for the sort to work
+ private String id;
+
+ @Field(type = FieldType.Text)
+ @Nullable private String lotrCharacter;
+
+ public LOTRCharacter(@Nullable String id, @Nullable String lotrCharacter) {
+ this.id = id;
+ this.lotrCharacter = lotrCharacter;
+ }
+
+ @Nullable
+ public String getId() {
+ return id;
+ }
+
+ public void setId(@Nullable String id) {
+ this.id = id;
+ }
+
+ @Nullable
+ public String getLotrCharacter() {
+ return lotrCharacter;
+ }
+
+ public void setLotrCharacter(@Nullable String lotrCharacter) {
+ this.lotrCharacter = lotrCharacter;
+ }
+ }
+
+ interface SampleElasticsearchRepository
+ extends ReactiveElasticsearchRepository