Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6654eaa38f | |||
| ebdc57e4b2 | |||
| 4cbfef39c6 | |||
| 8ad2e8e0a0 | |||
| 795e1ef60a | |||
| a08ffc85cf | |||
| c3eb590afe | |||
| fa065c1f27 | |||
| 5706fc0d3f | |||
| ad68771825 | |||
| eb5c6872d9 | |||
| 4ee59bb52f | |||
| ffdbea4dba | |||
| 7c1bc087ba | |||
| 475df8ef80 | |||
| 78bef3105c | |||
| 81d40611b9 | |||
| 446869154f | |||
| 836187c170 | |||
| 87427d96a2 | |||
| 4803ac2f98 |
@@ -5,12 +5,12 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>6.1.0-M2</version>
|
||||
<version>6.1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>4.1.0-M2</version>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
@@ -18,14 +18,14 @@
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
|
||||
<properties>
|
||||
<springdata.commons>4.1.0-M2</springdata.commons>
|
||||
<springdata.commons>4.1.0-SNAPSHOT</springdata.commons>
|
||||
|
||||
<!-- version of the ElasticsearchClient -->
|
||||
<elasticsearch-java>9.3.1</elasticsearch-java>
|
||||
<elasticsearch-rest-client>9.3.1</elasticsearch-rest-client>
|
||||
<elasticsearch-java>9.4.1</elasticsearch-java>
|
||||
<elasticsearch-rest-client>9.4.1</elasticsearch-rest-client>
|
||||
|
||||
<hoverfly>0.20.2</hoverfly>
|
||||
<log4j>2.25.3</log4j>
|
||||
<log4j>2.25.4</log4j>
|
||||
<jsonassert>1.5.3</jsonassert>
|
||||
<wiremock>3.9.2</wiremock>
|
||||
|
||||
@@ -499,8 +499,20 @@
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
|
||||
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[[new-features.6-1-0]]
|
||||
== New in Spring Data Elasticsearch 6.1
|
||||
|
||||
* Upgrade to Elasticsearch 9.3.1
|
||||
* Upgrade to Elasticsearch 9.4.1
|
||||
* Add support to use `IndexCoordinates` as repository query parameter
|
||||
* Add support for includeNamedQueriesScore in Query
|
||||
* Add support for Micrometer observation.
|
||||
|
||||
@@ -6,10 +6,10 @@ The following table shows the Elasticsearch and Spring versions that are used by
|
||||
[cols="^,^,^,^",options="header"]
|
||||
|===
|
||||
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
|
||||
| 2026.0 | 6.1.x | 9.3.1 | 7.0.x
|
||||
| 2026.0 | 6.1.x | 9.4.1 | 7.0.x
|
||||
| 2025.1 | 6.0.x | 9.2.2 | 7.0.x
|
||||
| 2025.0 | 5.5.x | 8.18.1 | 6.2.x
|
||||
| 2024.1 | 5.4.xfootnote:oom[Out of maintenance] | 8.15.5 | 6.1.x
|
||||
| 2025.0 | 5.5.xfootnote:oom[Out of maintenance] | 8.18.1 | 6.2.x
|
||||
| 2024.1 | 5.4.xfootnote:oom[] | 8.15.5 | 6.1.x
|
||||
| 2024.0 | 5.3.xfootnote:oom[] | 8.13.4 | 6.1.x
|
||||
| 2023.1 (Vaughan) | 5.2.xfootnote:oom[] | 8.11.1 | 6.1.x
|
||||
| 2023.0 (Ullmann) | 5.1.xfootnote:oom[] | 8.7.1 | 6.0.x
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
[[elasticsearch.projections]]
|
||||
= Projections
|
||||
|
||||
[[elasticsearch.projections.limitations]]
|
||||
== Spring Data Elasticsearch Projection Limitations
|
||||
|
||||
This chapter is pulled in from the Spring Data Commons documentation, but does not apply to Spring Data Elasticsearch.
|
||||
|
||||
IMPORTANT: Interface-based projections are not supported in Spring Data Elasticsearch repository query methods.
|
||||
|
||||
To limit the fields returned from Elasticsearch, use the xref:elasticsearch/repositories/elasticsearch-repositories.adoc#elasticsearch.repositories.annotations.sourcefilters[`@SourceFilters`] annotation on your repository methods instead.
|
||||
|
||||
include::{commons}@data-commons::page$repositories/projections.adoc[leveloffset=+1]
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch;
|
||||
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Illia Ulianov
|
||||
@@ -42,6 +43,6 @@ public class BulkFailureException extends DataRetrievalFailureException {
|
||||
* @author Illia Ulianov
|
||||
* @since 5.2
|
||||
*/
|
||||
public record FailureDetails(Integer status, String errorMessage) {
|
||||
public record FailureDetails(Integer status, @Nullable String errorMessage) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jspecify.annotations.Nullable;
|
||||
public class ElasticsearchErrorCause {
|
||||
@Nullable private final String type;
|
||||
|
||||
private final String reason;
|
||||
@Nullable private final String reason;
|
||||
|
||||
@Nullable private final String stackTrace;
|
||||
|
||||
@@ -38,7 +38,7 @@ public class ElasticsearchErrorCause {
|
||||
|
||||
private final List<ElasticsearchErrorCause> suppressed;
|
||||
|
||||
public ElasticsearchErrorCause(@Nullable String type, String reason, @Nullable String stackTrace,
|
||||
public ElasticsearchErrorCause(@Nullable String type, @Nullable String reason, @Nullable String stackTrace,
|
||||
@Nullable ElasticsearchErrorCause causedBy, List<ElasticsearchErrorCause> rootCause,
|
||||
List<ElasticsearchErrorCause> suppressed) {
|
||||
this.type = type;
|
||||
@@ -54,7 +54,7 @@ public class ElasticsearchErrorCause {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
public @Nullable String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.annotations;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.aot;
|
||||
|
||||
+154
-154
@@ -24,6 +24,14 @@ import co.elastic.clients.elasticsearch.core.search.Hit;
|
||||
import co.elastic.clients.elasticsearch.core.search.NestedIdentity;
|
||||
import co.elastic.clients.json.JsonData;
|
||||
import co.elastic.clients.json.JsonpMapper;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -36,13 +44,6 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentAdapte
|
||||
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utility class to adapt different Elasticsearch responses to a
|
||||
* {@link org.springframework.data.elasticsearch.core.document.Document}
|
||||
@@ -54,188 +55,187 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
final class DocumentAdapters {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
|
||||
private static final Log LOGGER = LogFactory.getLog(DocumentAdapters.class);
|
||||
|
||||
private DocumentAdapters() {
|
||||
}
|
||||
private DocumentAdapters() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link SearchDocument} from a {@link Hit} returned by the Elasticsearch client.
|
||||
*
|
||||
* @param hit the hit object
|
||||
* @param jsonpMapper to map JsonData objects
|
||||
* @return the created {@link SearchDocument}
|
||||
*/
|
||||
public static SearchDocument from(Hit<?> hit, JsonpMapper jsonpMapper) {
|
||||
/**
|
||||
* Creates a {@link SearchDocument} from a {@link Hit} returned by the Elasticsearch client.
|
||||
*
|
||||
* @param hit the hit object
|
||||
* @param jsonpMapper to map JsonData objects
|
||||
* @return the created {@link SearchDocument}
|
||||
*/
|
||||
public static SearchDocument from(Hit<?> hit, JsonpMapper jsonpMapper) {
|
||||
|
||||
Assert.notNull(hit, "hit must not be null");
|
||||
Assert.notNull(hit, "hit must not be null");
|
||||
|
||||
Map<String, List<String>> highlightFields = hit.highlight();
|
||||
Map<String, List<String>> highlightFields = hit.highlight();
|
||||
|
||||
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
|
||||
hit.innerHits().forEach((name, innerHitsResult) -> {
|
||||
// noinspection ReturnOfNull
|
||||
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null,
|
||||
searchDocument -> null, jsonpMapper));
|
||||
});
|
||||
Map<String, SearchDocumentResponse> innerHits = new LinkedHashMap<>();
|
||||
hit.innerHits().forEach((name, innerHitsResult) -> {
|
||||
// noinspection ReturnOfNull
|
||||
innerHits.put(name, SearchDocumentResponseBuilder.from(innerHitsResult.hits(), null, null, null, 0, null, null,
|
||||
searchDocument -> null, jsonpMapper));
|
||||
});
|
||||
|
||||
NestedMetaData nestedMetaData = from(hit.nested());
|
||||
NestedMetaData nestedMetaData = from(hit.nested());
|
||||
|
||||
Explanation explanation = from(hit.explanation());
|
||||
Explanation explanation = from(hit.explanation());
|
||||
|
||||
Map<String, Double> matchedQueries = hit.matchedQueries();
|
||||
Map<String, Double> matchedQueries = hit.matchedQueries();
|
||||
|
||||
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
|
||||
StringBuilder sb = new StringBuilder("{");
|
||||
final boolean[] firstField = {true};
|
||||
hit.fields().forEach((key, jsonData) -> {
|
||||
if (!firstField[0]) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append('"').append(key).append("\":") //
|
||||
.append(jsonData.toJson(jsonpMapper).toString());
|
||||
firstField[0] = false;
|
||||
});
|
||||
sb.append('}');
|
||||
return new EntityAsMap().fromJson(sb.toString());
|
||||
};
|
||||
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
|
||||
StringBuilder sb = new StringBuilder("{");
|
||||
final boolean[] firstField = { true };
|
||||
hit.fields().forEach((key, jsonData) -> {
|
||||
if (!firstField[0]) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append('"').append(key).append("\":") //
|
||||
.append(jsonData.toJson(jsonpMapper).toString());
|
||||
firstField[0] = false;
|
||||
});
|
||||
sb.append('}');
|
||||
return new EntityAsMap().fromJson(sb.toString());
|
||||
};
|
||||
|
||||
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
|
||||
EntityAsMap hitFieldsAsMap = fromFields.apply(hit.fields());
|
||||
|
||||
Map<String, List<Object>> documentFields = new LinkedHashMap<>();
|
||||
hitFieldsAsMap.forEach((key, value) -> {
|
||||
if (value instanceof List) {
|
||||
// noinspection unchecked
|
||||
documentFields.put(key, (List<Object>) value);
|
||||
} else {
|
||||
documentFields.put(key, Collections.singletonList(value));
|
||||
}
|
||||
});
|
||||
Map<String, List<@Nullable Object>> documentFields = new LinkedHashMap<>();
|
||||
hitFieldsAsMap.forEach((key, value) -> {
|
||||
if (value instanceof List) {
|
||||
// noinspection unchecked
|
||||
documentFields.put(key, (List<Object>) value);
|
||||
} else {
|
||||
documentFields.put(key, Collections.singletonList(value));
|
||||
}
|
||||
});
|
||||
|
||||
Document document;
|
||||
Object source = hit.source();
|
||||
if (source == null) {
|
||||
document = Document.from(hitFieldsAsMap);
|
||||
} else {
|
||||
if (source instanceof EntityAsMap entityAsMap) {
|
||||
document = Document.from(entityAsMap);
|
||||
} else if (source instanceof JsonData jsonData) {
|
||||
document = Document.from(jsonData.to(EntityAsMap.class));
|
||||
} else {
|
||||
Document document;
|
||||
Object source = hit.source();
|
||||
if (source == null) {
|
||||
document = Document.from(hitFieldsAsMap);
|
||||
} else {
|
||||
if (source instanceof EntityAsMap entityAsMap) {
|
||||
document = Document.from(entityAsMap);
|
||||
} else if (source instanceof JsonData jsonData) {
|
||||
document = Document.from(jsonData.to(EntityAsMap.class));
|
||||
} else {
|
||||
|
||||
if (LOGGER.isWarnEnabled()) {
|
||||
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
|
||||
}
|
||||
document = Document.create();
|
||||
}
|
||||
}
|
||||
document.setIndex(hit.index());
|
||||
document.setId(hit.id());
|
||||
if (LOGGER.isWarnEnabled()) {
|
||||
LOGGER.warn(String.format("Cannot map from type " + source.getClass().getName()));
|
||||
}
|
||||
document = Document.create();
|
||||
}
|
||||
}
|
||||
document.setIndex(hit.index());
|
||||
document.setId(hit.id());
|
||||
|
||||
if (hit.version() != null) {
|
||||
document.setVersion(hit.version());
|
||||
}
|
||||
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
|
||||
// old client
|
||||
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
|
||||
if (hit.version() != null) {
|
||||
document.setVersion(hit.version());
|
||||
}
|
||||
document.setSeqNo(hit.seqNo() != null && hit.seqNo() >= 0 ? hit.seqNo() : -2); // -2 was the default value in the
|
||||
// old client
|
||||
document.setPrimaryTerm(hit.primaryTerm() != null && hit.primaryTerm() > 0 ? hit.primaryTerm() : 0);
|
||||
|
||||
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
|
||||
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
|
||||
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
|
||||
}
|
||||
float score = hit.score() != null ? hit.score().floatValue() : Float.NaN;
|
||||
return new SearchDocumentAdapter(document, score, hit.sort().stream().map(TypeUtils::toObject).toArray(),
|
||||
documentFields, highlightFields, innerHits, nestedMetaData, explanation, matchedQueries, hit.routing());
|
||||
}
|
||||
|
||||
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
|
||||
public static SearchDocument from(CompletionSuggestOption<EntityAsMap> completionSuggestOption) {
|
||||
|
||||
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
|
||||
: Document.create();
|
||||
document.setIndex(completionSuggestOption.index());
|
||||
Document document = completionSuggestOption.source() != null ? Document.from(completionSuggestOption.source())
|
||||
: Document.create();
|
||||
document.setIndex(completionSuggestOption.index());
|
||||
|
||||
if (completionSuggestOption.id() != null) {
|
||||
document.setId(completionSuggestOption.id());
|
||||
}
|
||||
if (completionSuggestOption.id() != null) {
|
||||
document.setId(completionSuggestOption.id());
|
||||
}
|
||||
|
||||
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
|
||||
return new SearchDocumentAdapter(document, score, new Object[]{}, Collections.emptyMap(), Collections.emptyMap(),
|
||||
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
|
||||
}
|
||||
float score = completionSuggestOption.score() != null ? completionSuggestOption.score().floatValue() : Float.NaN;
|
||||
return new SearchDocumentAdapter(document, score, new Object[] {}, Collections.emptyMap(), Collections.emptyMap(),
|
||||
Collections.emptyMap(), null, null, null, completionSuggestOption.routing());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Explanation from(co.elastic.clients.elasticsearch.core.explain.@Nullable Explanation explanation) {
|
||||
@Nullable
|
||||
private static Explanation from(co.elastic.clients.elasticsearch.core.explain.@Nullable Explanation explanation) {
|
||||
|
||||
if (explanation == null) {
|
||||
return null;
|
||||
}
|
||||
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
|
||||
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
|
||||
}
|
||||
if (explanation == null) {
|
||||
return null;
|
||||
}
|
||||
List<Explanation> details = explanation.details().stream().map(DocumentAdapters::from).collect(Collectors.toList());
|
||||
return new Explanation(true, (double) explanation.value(), explanation.description(), details);
|
||||
}
|
||||
|
||||
private static Explanation from(ExplanationDetail explanationDetail) {
|
||||
private static Explanation from(ExplanationDetail explanationDetail) {
|
||||
|
||||
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
|
||||
.collect(Collectors.toList());
|
||||
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
|
||||
}
|
||||
List<Explanation> details = explanationDetail.details().stream().map(DocumentAdapters::from)
|
||||
.collect(Collectors.toList());
|
||||
return new Explanation(null, (double) explanationDetail.value(), explanationDetail.description(), details);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
|
||||
@Nullable
|
||||
private static NestedMetaData from(@Nullable NestedIdentity nestedIdentity) {
|
||||
|
||||
if (nestedIdentity == null) {
|
||||
return null;
|
||||
}
|
||||
if (nestedIdentity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NestedMetaData child = from(nestedIdentity.nested());
|
||||
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
|
||||
}
|
||||
NestedMetaData child = from(nestedIdentity.nested());
|
||||
return NestedMetaData.of(nestedIdentity.field(), nestedIdentity.offset(), child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
|
||||
*
|
||||
* @param getResponse the response instance
|
||||
* @return the Document
|
||||
*/
|
||||
@Nullable
|
||||
public static Document from(GetResult<EntityAsMap> getResponse) {
|
||||
/**
|
||||
* Creates a {@link Document} from a {@link GetResponse} where the found document is contained as {@link EntityAsMap}.
|
||||
*
|
||||
* @param getResponse the response instance
|
||||
* @return the Document
|
||||
*/
|
||||
@Nullable
|
||||
public static Document from(GetResult<EntityAsMap> getResponse) {
|
||||
|
||||
Assert.notNull(getResponse, "getResponse must not be null");
|
||||
Assert.notNull(getResponse, "getResponse must not be null");
|
||||
|
||||
if (!getResponse.found()) {
|
||||
return null;
|
||||
}
|
||||
if (!getResponse.found()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
|
||||
document.setIndex(getResponse.index());
|
||||
document.setId(getResponse.id());
|
||||
Document document = getResponse.source() != null ? Document.from(getResponse.source()) : Document.create();
|
||||
document.setIndex(getResponse.index());
|
||||
document.setId(getResponse.id());
|
||||
|
||||
if (getResponse.version() != null) {
|
||||
document.setVersion(getResponse.version());
|
||||
}
|
||||
if (getResponse.version() != null) {
|
||||
document.setVersion(getResponse.version());
|
||||
}
|
||||
|
||||
if (getResponse.seqNo() != null) {
|
||||
document.setSeqNo(getResponse.seqNo());
|
||||
}
|
||||
if (getResponse.seqNo() != null) {
|
||||
document.setSeqNo(getResponse.seqNo());
|
||||
}
|
||||
|
||||
if (getResponse.primaryTerm() != null) {
|
||||
document.setPrimaryTerm(getResponse.primaryTerm());
|
||||
}
|
||||
if (getResponse.primaryTerm() != null) {
|
||||
document.setPrimaryTerm(getResponse.primaryTerm());
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
|
||||
* {@link EntityAsMap} instances.
|
||||
*
|
||||
* @param mgetResponse the response instance
|
||||
* @return list of multiget items
|
||||
*/
|
||||
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
|
||||
/**
|
||||
* Creates a list of {@link MultiGetItem}s from a {@link MgetResponse} where the data is contained as
|
||||
* {@link EntityAsMap} instances.
|
||||
*
|
||||
* @param mgetResponse the response instance
|
||||
* @return list of multiget items
|
||||
*/
|
||||
public static List<MultiGetItem<Document>> from(MgetResponse<EntityAsMap> mgetResponse) {
|
||||
|
||||
Assert.notNull(mgetResponse, "mgetResponse must not be null");
|
||||
Assert.notNull(mgetResponse, "mgetResponse must not be null");
|
||||
|
||||
return mgetResponse.docs().stream() //
|
||||
.map(itemResponse -> MultiGetItem.of( //
|
||||
itemResponse.isFailure() ? null : from(itemResponse.result()), //
|
||||
ResponseConverter.getFailure(itemResponse)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return mgetResponse.docs().stream() //
|
||||
.map(itemResponse -> MultiGetItem.of( //
|
||||
itemResponse.isFailure() ? null : from(itemResponse.result()), //
|
||||
ResponseConverter.getFailure(itemResponse)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -114,7 +114,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Map<String, Object> settings) {
|
||||
public boolean create(Map<String, @Nullable Object> settings) {
|
||||
|
||||
Assert.notNull(settings, "settings must not be null");
|
||||
|
||||
@@ -122,7 +122,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Map<String, Object> settings, Document mapping) {
|
||||
public boolean create(Map<String, @Nullable Object> settings, Document mapping) {
|
||||
|
||||
Assert.notNull(settings, "settings must not be null");
|
||||
Assert.notNull(mapping, "mapping must not be null");
|
||||
@@ -135,7 +135,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
|
||||
return doCreate(getIndexCoordinates(), createSettings(), createMapping());
|
||||
}
|
||||
|
||||
protected boolean doCreate(IndexCoordinates indexCoordinates, Map<String, Object> settings,
|
||||
protected boolean doCreate(IndexCoordinates indexCoordinates, Map<String, @Nullable Object> settings,
|
||||
@Nullable Document mapping) {
|
||||
Set<Alias> aliases = (boundClass != null) ? getAliasesFor(boundClass) : new HashSet<>();
|
||||
CreateIndexSettings indexSettings = CreateIndexSettings.builder(indexCoordinates)
|
||||
@@ -233,7 +233,7 @@ public class IndicesTemplate extends ChildTemplate<ElasticsearchTransport, Elast
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMapping() {
|
||||
public Map<String, @Nullable Object> getMapping() {
|
||||
|
||||
IndexCoordinates indexCoordinates = getIndexCoordinates();
|
||||
GetMappingRequest getMappingRequest = requestConverter.indicesGetMappingRequest(indexCoordinates);
|
||||
|
||||
+26
-27
@@ -18,9 +18,30 @@ package org.springframework.data.elasticsearch.client.elc;
|
||||
import static co.elastic.clients.util.ApiTypeHelper.*;
|
||||
import static org.springframework.data.elasticsearch.client.elc.TypeUtils.*;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.Result;
|
||||
import co.elastic.clients.elasticsearch.core.*;
|
||||
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
|
||||
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
|
||||
import co.elastic.clients.json.JsonpMapper;
|
||||
import co.elastic.clients.transport.Version;
|
||||
import co.elastic.clients.transport.endpoints.BooleanResponse;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.BeansException;
|
||||
@@ -52,28 +73,6 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.Result;
|
||||
import co.elastic.clients.elasticsearch.core.*;
|
||||
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
|
||||
import co.elastic.clients.elasticsearch.core.search.ResponseBody;
|
||||
import co.elastic.clients.json.JsonpMapper;
|
||||
import co.elastic.clients.transport.Version;
|
||||
import co.elastic.clients.transport.endpoints.BooleanResponse;
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Implementation of {@link org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations} using the new
|
||||
* Elasticsearch client.
|
||||
@@ -269,7 +268,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
ExistsRequest existsRequest = requestConverter.documentExistsRequest(id, routingResolver.getRouting(), index);
|
||||
|
||||
return Mono.from(execute(
|
||||
((ClientCallback<@NonNull Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
|
||||
((ClientCallback<Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
|
||||
.map(BooleanResponse::value) //
|
||||
.onErrorReturn(NoSuchIndexException.class, false);
|
||||
}
|
||||
@@ -381,7 +380,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
|
||||
for (BulkResponseItem item : bulkResponse.items()) {
|
||||
|
||||
if (item.error() != null) {
|
||||
if (item.error() != null && item.id() != null) {
|
||||
failedDocuments.put(item.id(), new BulkFailureException.FailureDetails(item.status(), item.error().reason()));
|
||||
}
|
||||
}
|
||||
@@ -538,7 +537,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
List<Object> sortOptions = hits.get(hits.size() - 1).sort().stream().map(TypeUtils::toObject)
|
||||
List<Object> sortOptions = hits.get(hits.size() - 1).sort().stream().map(TypeUtils::toObjectNotNull)
|
||||
.collect(Collectors.toList());
|
||||
baseQuery.setSearchAfter(sortOptions);
|
||||
SearchRequest followSearchRequest = requestConverter.searchRequest(baseQuery,
|
||||
@@ -632,8 +631,8 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
SearchRequest searchRequest = requestConverter.searchRequest(query, routingResolver.getRouting(), clazz, index,
|
||||
false);
|
||||
|
||||
// noinspection unchecked
|
||||
SearchDocumentCallback<T> callback = new ReadSearchDocumentCallback<>((Class<T>) clazz, index);
|
||||
|
||||
SearchDocumentResponse.EntityCreator<T> entityCreator = searchDocument -> callback.toEntity(searchDocument)
|
||||
.toFuture();
|
||||
|
||||
|
||||
+4
-4
@@ -108,7 +108,7 @@ public class ReactiveIndicesTemplate
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> create(Map<String, Object> settings) {
|
||||
public Mono<Boolean> create(Map<String, @Nullable Object> settings) {
|
||||
|
||||
Assert.notNull(settings, "settings must not be null");
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ReactiveIndicesTemplate
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> create(Map<String, Object> settings, Document mapping) {
|
||||
public Mono<Boolean> create(Map<String, @Nullable Object> settings, Document mapping) {
|
||||
|
||||
Assert.notNull(settings, "settings must not be null");
|
||||
Assert.notNull(mapping, "mapping must not be null");
|
||||
@@ -132,7 +132,7 @@ public class ReactiveIndicesTemplate
|
||||
doCreate(getIndexCoordinates(), settings, mapping))); //
|
||||
}
|
||||
|
||||
private Mono<Boolean> doCreate(IndexCoordinates indexCoordinates, Map<String, Object> settings,
|
||||
private Mono<Boolean> doCreate(IndexCoordinates indexCoordinates, Map<String, @Nullable Object> settings,
|
||||
@Nullable Document mapping) {
|
||||
Set<Alias> aliases = (boundClass != null) ? getAliasesFor(boundClass) : new HashSet<>();
|
||||
CreateIndexSettings indexSettings = CreateIndexSettings.builder(indexCoordinates)
|
||||
@@ -270,7 +270,7 @@ public class ReactiveIndicesTemplate
|
||||
return getAliases(null, indexNames);
|
||||
}
|
||||
|
||||
private Mono<Map<String, Set<AliasData>>> getAliases(@Nullable String[] aliasNames, @Nullable String[] indexNames) {
|
||||
private Mono<Map<String, Set<AliasData>>> getAliases(String@Nullable [] aliasNames, String@Nullable [] indexNames) {
|
||||
|
||||
GetAliasRequest getAliasRequest = requestConverter.indicesGetAliasRequest(aliasNames, indexNames);
|
||||
Mono<GetAliasResponse> getAliasResponse = Mono.from(execute(client -> client.getAlias(getAliasRequest)));
|
||||
|
||||
+77
-83
@@ -74,6 +74,7 @@ import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -113,6 +114,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author cdalxndr
|
||||
* @author scoobyzhang
|
||||
* @author Haibo Liu
|
||||
* @author Steven Pearce
|
||||
* @since 4.4
|
||||
*/
|
||||
class RequestConverter extends AbstractQueryProcessor {
|
||||
@@ -173,17 +175,9 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
private co.elastic.clients.elasticsearch.indices.Alias.Builder buildAlias(AliasActionParameters parameters,
|
||||
co.elastic.clients.elasticsearch.indices.Alias.Builder aliasBuilder) {
|
||||
|
||||
if (parameters.getRouting() != null) {
|
||||
aliasBuilder.routing(parameters.getRouting());
|
||||
}
|
||||
|
||||
if (parameters.getIndexRouting() != null) {
|
||||
aliasBuilder.indexRouting(parameters.getIndexRouting());
|
||||
}
|
||||
|
||||
if (parameters.getSearchRouting() != null) {
|
||||
aliasBuilder.searchRouting(parameters.getSearchRouting());
|
||||
}
|
||||
getRouting(parameters.getRouting()).ifPresent(aliasBuilder::routing);
|
||||
getRouting(parameters.getIndexRouting()).ifPresent(aliasBuilder::indexRouting);
|
||||
getRouting(parameters.getSearchRouting()).ifPresent(aliasBuilder::searchRouting);
|
||||
|
||||
if (parameters.getHidden() != null) {
|
||||
aliasBuilder.isHidden(parameters.getHidden());
|
||||
@@ -239,12 +233,16 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
Map<String, co.elastic.clients.elasticsearch.indices.Alias> aliases = new HashMap<>();
|
||||
for (Alias alias : indexSettings.getAliases()) {
|
||||
co.elastic.clients.elasticsearch.indices.Alias esAlias = co.elastic.clients.elasticsearch.indices.Alias
|
||||
.of(ab -> ab.filter(getQuery(alias.getFilter(), null))
|
||||
.routing(alias.getRouting())
|
||||
.indexRouting(alias.getIndexRouting())
|
||||
.searchRouting(alias.getSearchRouting())
|
||||
.isHidden(alias.getHidden())
|
||||
.isWriteIndex(alias.getWriteIndex()));
|
||||
.of(ab -> {
|
||||
co.elastic.clients.elasticsearch.indices.Alias.Builder aliasBuilder = ab.filter(getQuery(alias.getFilter(), null))
|
||||
.isHidden(alias.getHidden())
|
||||
.isWriteIndex(alias.getWriteIndex());
|
||||
getRouting(alias.getRouting()).ifPresent(aliasBuilder::routing);
|
||||
getRouting(alias.getIndexRouting()).ifPresent(aliasBuilder::indexRouting);
|
||||
getRouting(alias.getSearchRouting()).ifPresent(aliasBuilder::searchRouting);
|
||||
|
||||
return aliasBuilder;
|
||||
});
|
||||
aliases.put(alias.getAlias(), esAlias);
|
||||
}
|
||||
|
||||
@@ -318,10 +316,11 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
addActionBuilder //
|
||||
.indices(Arrays.asList(parameters.getIndices())) //
|
||||
.isHidden(parameters.getHidden()) //
|
||||
.isWriteIndex(parameters.getWriteIndex()) //
|
||||
.routing(parameters.getRouting()) //
|
||||
.indexRouting(parameters.getIndexRouting()) //
|
||||
.searchRouting(parameters.getSearchRouting()); //
|
||||
.isWriteIndex(parameters.getWriteIndex()); //
|
||||
|
||||
getRouting(parameters.getRouting()).ifPresent(addActionBuilder::routing);
|
||||
getRouting(parameters.getIndexRouting()).ifPresent(addActionBuilder::indexRouting);
|
||||
getRouting(parameters.getSearchRouting()).ifPresent(addActionBuilder::searchRouting);
|
||||
|
||||
if (parameters.getAliases() != null) {
|
||||
addActionBuilder.aliases(Arrays.asList(parameters.getAliases()));
|
||||
@@ -589,10 +588,11 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
builder.version(query.getVersion()).versionType(versionType);
|
||||
}
|
||||
|
||||
builder //
|
||||
.ifSeqNo(query.getSeqNo()) //
|
||||
.ifPrimaryTerm(query.getPrimaryTerm()) //
|
||||
.routing(query.getRouting()); //
|
||||
builder
|
||||
.ifSeqNo(query.getSeqNo())
|
||||
.ifPrimaryTerm(query.getPrimaryTerm());
|
||||
|
||||
getRouting(query.getRouting()).ifPresent(builder::routing);
|
||||
|
||||
if (query.getOpType() != null) {
|
||||
switch (query.getOpType()) {
|
||||
@@ -642,8 +642,9 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
|
||||
builder //
|
||||
.ifSeqNo(query.getSeqNo()) //
|
||||
.ifPrimaryTerm(query.getPrimaryTerm()) //
|
||||
.routing(query.getRouting()); //
|
||||
.ifPrimaryTerm(query.getPrimaryTerm()); //
|
||||
|
||||
getRouting(query.getRouting()).ifPresent(builder::routing);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@@ -684,8 +685,9 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
|
||||
builder //
|
||||
.ifSeqNo(query.getSeqNo()) //
|
||||
.ifPrimaryTerm(query.getPrimaryTerm()) //
|
||||
.routing(query.getRouting()); //
|
||||
.ifPrimaryTerm(query.getPrimaryTerm()); //
|
||||
|
||||
getRouting(query.getRouting()).ifPresent(builder::routing);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@@ -722,11 +724,12 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
});
|
||||
|
||||
uob
|
||||
.routing(query.getRouting())
|
||||
.ifSeqNo(query.getIfSeqNo())
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm())
|
||||
.retryOnConflict(query.getRetryOnConflict());
|
||||
|
||||
getRouting(query.getRouting()).ifPresent(uob::routing);
|
||||
|
||||
// no refresh, timeout, waitForActiveShards on UpdateOperation or UpdateAction
|
||||
|
||||
return uob.build();
|
||||
@@ -776,9 +779,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
builder.pipeline(bulkOptions.getPipeline());
|
||||
}
|
||||
|
||||
if (bulkOptions.getRoutingId() != null) {
|
||||
builder.routing(bulkOptions.getRoutingId());
|
||||
}
|
||||
getRouting(bulkOptions.getRoutingId()).ifPresent(builder::routing);
|
||||
|
||||
List<BulkOperation> operations = queries.stream().map(query -> {
|
||||
BulkOperation.Builder ob = new BulkOperation.Builder();
|
||||
@@ -805,10 +806,13 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
Assert.notNull(id, "id must not be null");
|
||||
Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
|
||||
|
||||
return GetRequest.of(grb -> grb //
|
||||
.index(indexCoordinates.getIndexName()) //
|
||||
.id(id) //
|
||||
.routing(routing));
|
||||
return GetRequest.of(grb -> {
|
||||
GetRequest.Builder builder = grb //
|
||||
.index(indexCoordinates.getIndexName()) //
|
||||
.id(id); //
|
||||
getRouting(routing).ifPresent(builder::routing);
|
||||
return builder;
|
||||
});
|
||||
}
|
||||
|
||||
public co.elastic.clients.elasticsearch.core.ExistsRequest documentExistsRequest(String id, @Nullable String routing,
|
||||
@@ -817,10 +821,13 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
Assert.notNull(id, "id must not be null");
|
||||
Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
|
||||
|
||||
return co.elastic.clients.elasticsearch.core.ExistsRequest.of(erb -> erb
|
||||
.index(indexCoordinates.getIndexName())
|
||||
.id(id)
|
||||
.routing(routing));
|
||||
return co.elastic.clients.elasticsearch.core.ExistsRequest.of(erb -> {
|
||||
co.elastic.clients.elasticsearch.core.ExistsRequest.Builder builder = erb
|
||||
.index(indexCoordinates.getIndexName())
|
||||
.id(id);
|
||||
getRouting(routing).ifPresent(builder::routing);
|
||||
return builder;
|
||||
});
|
||||
}
|
||||
|
||||
public <T> MgetRequest documentMgetRequest(Query query, Class<T> clazz, IndexCoordinates index) {
|
||||
@@ -838,11 +845,14 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
SourceConfig sourceConfig = getSourceConfig(query);
|
||||
|
||||
List<MultiGetOperation> multiGetOperations = query.getIdsWithRouting().stream()
|
||||
.map(idWithRouting -> MultiGetOperation.of(mgo -> mgo //
|
||||
.index(index.getIndexName()) //
|
||||
.id(idWithRouting.id()) //
|
||||
.routing(idWithRouting.routing()) //
|
||||
.source(sourceConfig)))
|
||||
.map(idWithRouting -> MultiGetOperation.of(mgo -> {
|
||||
MultiGetOperation.Builder builder = mgo //
|
||||
.index(index.getIndexName()) //
|
||||
.id(idWithRouting.id()) //
|
||||
.source(sourceConfig);
|
||||
getRouting(idWithRouting.routing()).ifPresent(builder::routing);
|
||||
return builder;
|
||||
}))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return MgetRequest.of(mg -> mg//
|
||||
@@ -964,10 +974,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
|
||||
return DeleteRequest.of(r -> {
|
||||
r.id(id).index(index.getIndexName());
|
||||
|
||||
if (routing != null) {
|
||||
r.routing(routing);
|
||||
}
|
||||
getRouting(routing).ifPresent(r::routing);
|
||||
r.refresh(refresh(refreshPolicy));
|
||||
return r;
|
||||
});
|
||||
@@ -991,11 +998,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
|
||||
b.scroll(time(query.getScrollTime()));
|
||||
|
||||
if (query.getRoute() != null) {
|
||||
b.routing(query.getRoute());
|
||||
} else if (StringUtils.hasText(routing)) {
|
||||
b.routing(routing);
|
||||
}
|
||||
getRouting(query.getRoute(), routing).ifPresent(b::routing);
|
||||
|
||||
return b;
|
||||
});
|
||||
@@ -1015,11 +1018,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
.scroll(time(query.getScroll()))
|
||||
.scrollSize(query.getScrollSize());
|
||||
|
||||
if (query.getRouting() != null) {
|
||||
dqb.routing(query.getRouting());
|
||||
} else if (StringUtils.hasText(routing)) {
|
||||
dqb.routing(routing);
|
||||
}
|
||||
getRouting(query.getRouting(), routing).ifPresent(dqb::routing);
|
||||
|
||||
if (query.getQ() != null) {
|
||||
dqb.q(query.getQ())
|
||||
@@ -1099,7 +1098,6 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
uqb
|
||||
.doc(query.getDocument())
|
||||
.upsert(query.getUpsert())
|
||||
.routing(query.getRouting() != null ? query.getRouting() : routing)
|
||||
.scriptedUpsert(query.getScriptedUpsert())
|
||||
.docAsUpsert(query.getDocAsUpsert())
|
||||
.ifSeqNo(query.getIfSeqNo())
|
||||
@@ -1107,6 +1105,8 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
.refresh(query.getRefreshPolicy() != null ? refresh(query.getRefreshPolicy()) : refresh(refreshPolicy))
|
||||
.retryOnConflict(query.getRetryOnConflict());
|
||||
|
||||
getRouting(query.getRouting(), routing).ifPresent(uqb::routing);
|
||||
|
||||
if (query.getFetchSource() != null) {
|
||||
uqb.source(sc -> sc.fetch(query.getFetchSource()));
|
||||
}
|
||||
@@ -1149,13 +1149,14 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
ub //
|
||||
.index(Arrays.asList(index.getIndexNames())) //
|
||||
.refresh(refreshPolicy == RefreshPolicy.IMMEDIATE) //
|
||||
.routing(updateQuery.getRouting()) //
|
||||
.script(getScript(updateQuery.getScriptData())) //
|
||||
.maxDocs(updateQuery.getMaxDocs() != null ? Long.valueOf(updateQuery.getMaxDocs()) : null) //
|
||||
.pipeline(updateQuery.getPipeline()) //
|
||||
.requestsPerSecond(updateQuery.getRequestsPerSecond()) //
|
||||
.slices(slices(updateQuery.getSlices() != null ? Long.valueOf(updateQuery.getSlices()) : null));
|
||||
|
||||
getRouting(updateQuery.getRouting()).ifPresent(ub::routing);
|
||||
|
||||
if (updateQuery.getAbortOnVersionConflict() != null) {
|
||||
ub.conflicts(updateQuery.getAbortOnVersionConflict() ? Conflicts.Abort : Conflicts.Proceed);
|
||||
}
|
||||
@@ -1229,12 +1230,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
|
||||
builder.query(getQuery(query, clazz));
|
||||
|
||||
if (StringUtils.hasText(query.getRoute())) {
|
||||
builder.routing(query.getRoute());
|
||||
}
|
||||
if (StringUtils.hasText(routing)) {
|
||||
builder.routing(routing);
|
||||
}
|
||||
getRouting(query.getRoute(), routing).ifPresent(builder::routing);
|
||||
|
||||
addPostFilter(query, builder);
|
||||
|
||||
@@ -1401,11 +1397,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
.requestCache(query.getRequestCache()) //
|
||||
;
|
||||
|
||||
if (StringUtils.hasText(query.getRoute())) {
|
||||
h.routing(query.getRoute());
|
||||
} else if (StringUtils.hasText(routing)) {
|
||||
h.routing(routing);
|
||||
}
|
||||
getRouting(query.getRoute(), routing).ifPresent(h::routing);
|
||||
|
||||
if (query.getPreference() != null) {
|
||||
h.preference(query.getPreference());
|
||||
@@ -1451,11 +1443,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
builder.expandWildcards(expandWildcards(expandWildcards));
|
||||
}
|
||||
|
||||
if (query.getRoute() != null) {
|
||||
builder.routing(query.getRoute());
|
||||
} else if (StringUtils.hasText(routing)) {
|
||||
builder.routing(routing);
|
||||
}
|
||||
getRouting(query.getRoute(), routing).ifPresent(builder::routing);
|
||||
|
||||
if (query.getPreference() != null) {
|
||||
builder.preference(query.getPreference());
|
||||
@@ -1886,11 +1874,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
if (query.getSource() != null) {
|
||||
builder.source(so -> so.scriptString(query.getSource()));
|
||||
}
|
||||
if (query.getRoute() != null) {
|
||||
builder.routing(query.getRoute());
|
||||
} else if (StringUtils.hasText(routing)) {
|
||||
builder.routing(routing);
|
||||
}
|
||||
getRouting(query.getRoute(), routing).ifPresent(builder::routing);
|
||||
|
||||
var expandWildcards = query.getExpandWildcards();
|
||||
if (expandWildcards != null && !expandWildcards.isEmpty()) {
|
||||
@@ -1990,6 +1974,16 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<String> getRouting(@Nullable String routing) {
|
||||
if (StringUtils.hasText(routing)) {
|
||||
return Optional.of(routing);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
Optional<String> getRouting(@Nullable String routing1, @Nullable String routing2) {
|
||||
return getRouting(routing1).or(() -> getRouting(routing2));
|
||||
}
|
||||
|
||||
private VersionType retrieveVersionTypeFromPersistentEntity(@Nullable Class<?> clazz) {
|
||||
|
||||
ElasticsearchPersistentEntity<?> persistentEntity = getPersistentEntity(clazz);
|
||||
|
||||
+16
-12
@@ -22,7 +22,7 @@ import co.elastic.clients.elasticsearch._types.BulkIndexByScrollFailure;
|
||||
import co.elastic.clients.elasticsearch._types.ErrorCause;
|
||||
import co.elastic.clients.elasticsearch._types.Time;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
|
||||
import co.elastic.clients.elasticsearch.cluster.ComponentTemplateSummary;
|
||||
import co.elastic.clients.elasticsearch.cluster.ComponentTemplateSummaryRes;
|
||||
import co.elastic.clients.elasticsearch.cluster.GetComponentTemplateResponse;
|
||||
import co.elastic.clients.elasticsearch.cluster.HealthResponse;
|
||||
import co.elastic.clients.elasticsearch.core.DeleteByQueryResponse;
|
||||
@@ -66,6 +66,7 @@ import org.springframework.data.elasticsearch.core.reindex.ReindexResponse;
|
||||
import org.springframework.data.elasticsearch.core.script.Script;
|
||||
import org.springframework.data.elasticsearch.core.sql.SqlResponse;
|
||||
import org.springframework.data.elasticsearch.support.DefaultStringObjectMap;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -132,7 +133,7 @@ class ResponseConverter {
|
||||
.build();
|
||||
}
|
||||
|
||||
private TemplateResponseData clusterGetComponentTemplateData(ComponentTemplateSummary componentTemplateSummary) {
|
||||
private TemplateResponseData clusterGetComponentTemplateData(ComponentTemplateSummaryRes componentTemplateSummary) {
|
||||
|
||||
var mapping = typeMapping(componentTemplateSummary.mappings());
|
||||
var settings = new Settings();
|
||||
@@ -335,11 +336,11 @@ class ResponseConverter {
|
||||
.build();
|
||||
}
|
||||
|
||||
private TemplateResponseData indexGetComponentTemplateData(IndexTemplateSummary indexTemplateSummary,
|
||||
private TemplateResponseData indexGetComponentTemplateData(IndexTemplateSummaryWithRollover indexTemplateSummary,
|
||||
List<String> composedOf) {
|
||||
var mapping = typeMapping(indexTemplateSummary.mappings());
|
||||
|
||||
Function<IndexSettings, Settings> indexSettingsToSettings = indexSettings -> {
|
||||
Function<@Nullable IndexSettings, @Nullable Settings> indexSettingsToSettings = indexSettings -> {
|
||||
|
||||
if (indexSettings == null) {
|
||||
return null;
|
||||
@@ -497,7 +498,7 @@ class ResponseConverter {
|
||||
builder.withDeleted(response.deleted());
|
||||
}
|
||||
|
||||
if(response.updated() != null) {
|
||||
if (response.updated() != null) {
|
||||
builder.withUpdated(response.updated());
|
||||
}
|
||||
|
||||
@@ -574,17 +575,20 @@ class ResponseConverter {
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null -> null; !null -> !null")
|
||||
@Nullable
|
||||
static ElasticsearchErrorCause toErrorCause(@Nullable ErrorCause errorCause) {
|
||||
|
||||
if (errorCause != null) {
|
||||
return new ElasticsearchErrorCause( //
|
||||
errorCause.type(), //
|
||||
errorCause.reason(), //
|
||||
errorCause.stackTrace(), //
|
||||
toErrorCause(errorCause.causedBy()), //
|
||||
errorCause.rootCause().stream().map(ResponseConverter::toErrorCause).collect(Collectors.toList()), //
|
||||
errorCause.suppressed().stream().map(ResponseConverter::toErrorCause).collect(Collectors.toList()));
|
||||
return new ElasticsearchErrorCause(
|
||||
errorCause.type(),
|
||||
errorCause.reason(),
|
||||
errorCause.stackTrace(),
|
||||
toErrorCause(errorCause.causedBy()),
|
||||
(List<ElasticsearchErrorCause>) (errorCause.rootCause().stream()
|
||||
.map(ResponseConverter::toErrorCause).collect(Collectors.toList())),
|
||||
(List<ElasticsearchErrorCause>) (errorCause.suppressed().stream().map(ResponseConverter::toErrorCause)
|
||||
.collect(Collectors.toList())));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.EnumSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -144,6 +145,12 @@ final class TypeUtils {
|
||||
}
|
||||
}
|
||||
|
||||
static Object toObjectNotNull(FieldValue fieldValue) {
|
||||
|
||||
Objects.requireNonNull(fieldValue);
|
||||
return toObject(fieldValue);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Object toObject(@Nullable FieldValue fieldValue) {
|
||||
|
||||
@@ -485,7 +492,7 @@ final class TypeUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static IndexSettings indexSettings(@Nullable Map<String, Object> settings) {
|
||||
static IndexSettings indexSettings(@Nullable Map<String, @Nullable Object> settings) {
|
||||
return settings != null ? IndexSettings.of(b -> b.withJson(new StringReader(Document.from(settings).toJson())))
|
||||
: null;
|
||||
}
|
||||
|
||||
+8
-10
@@ -15,15 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.client.elc.aot;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
|
||||
import co.elastic.clients.elasticsearch.indices.IndexSettings;
|
||||
import co.elastic.clients.elasticsearch.indices.PutMappingRequest;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -38,10 +32,14 @@ public class ElasticsearchClientRuntimeHints implements RuntimeHintsRegistrar {
|
||||
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
|
||||
|
||||
hints.reflection()
|
||||
.registerType(TypeReference.of(IndexSettings.class), builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerType(TypeReference.of(PutMappingRequest.class), builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerType(TypeReference.of(RuntimeFieldType.class), builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerType(TypeReference.of(TypeMapping.class), builder -> builder.withField("_DESERIALIZER"));
|
||||
.registerTypeIfPresent(classLoader, "co.elastic.clients.elasticsearch.indices.IndexSettings",
|
||||
builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerTypeIfPresent(classLoader, "co.elastic.clients.elasticsearch.indices.PutMappingRequest",
|
||||
builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerTypeIfPresent(classLoader, "co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType",
|
||||
builder -> builder.withField("_DESERIALIZER"))
|
||||
.registerTypeIfPresent(classLoader, "co.elastic.clients.elasticsearch._types.mapping.TypeMapping",
|
||||
builder -> builder.withField("_DESERIALIZER"));
|
||||
|
||||
if (ClassUtils.isPresent("org.apache.http.impl.auth.BasicScheme",
|
||||
ElasticsearchClientRuntimeHints.class.getClassLoader())) {
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.client.elc.aot;
|
||||
|
||||
+1
-2
@@ -28,7 +28,6 @@ import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
@@ -181,7 +180,7 @@ public final class Rest5Clients {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) {
|
||||
private static HttpHost[] getHttpHosts(ClientConfiguration clientConfiguration) {
|
||||
List<InetSocketAddress> hosts = clientConfiguration.getEndpoints();
|
||||
boolean useSsl = clientConfiguration.useSsl();
|
||||
return hosts.stream()
|
||||
|
||||
+3
-5
@@ -21,10 +21,8 @@ import org.apache.http.protocol.HttpContext;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchClients;
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -107,7 +105,7 @@ public final class RestClients {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static HttpHost @NonNull [] getHttpHosts(ClientConfiguration clientConfiguration) {
|
||||
private static HttpHost[] getHttpHosts(ClientConfiguration clientConfiguration) {
|
||||
List<InetSocketAddress> hosts = clientConfiguration.getEndpoints();
|
||||
boolean useSsl = clientConfiguration.useSsl();
|
||||
return hosts.stream()
|
||||
@@ -130,10 +128,10 @@ public final class RestClients {
|
||||
record CustomHeaderInjector(Supplier<HttpHeaders> headersSupplier) implements HttpRequestInterceptor {
|
||||
|
||||
@Override
|
||||
public void process(HttpRequest request, HttpContext context) {
|
||||
public void process(@Nullable HttpRequest request, @Nullable HttpContext context) {
|
||||
HttpHeaders httpHeaders = headersSupplier.get();
|
||||
|
||||
if (httpHeaders != null && !httpHeaders.isEmpty()) {
|
||||
if (!httpHeaders.isEmpty() && request != null) {
|
||||
Arrays.stream(toHeaderArray(httpHeaders)).forEach(request::addHeader);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.client;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.client.util;
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.config;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@@ -98,7 +99,7 @@ public class ElasticsearchConfigurationSupport {
|
||||
protected Collection<String> getMappingBasePackages() {
|
||||
|
||||
Package mappingBasePackage = getClass().getPackage();
|
||||
return Collections.singleton(mappingBasePackage == null ? null : mappingBasePackage.getName());
|
||||
return mappingBasePackage == null ? Collections.emptyList() : List.of(mappingBasePackage.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.config;
|
||||
|
||||
+6
-2
@@ -59,6 +59,7 @@ import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.lang.Contract;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -260,7 +261,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
List<IndexedObjectInformation> indexedObjectInformationList = bulkIndex(indexQueries, index);
|
||||
Iterator<IndexedObjectInformation> iterator = indexedObjectInformationList.iterator();
|
||||
|
||||
// noinspection unchecked
|
||||
// noinspection unchecked,DataFlowIssue
|
||||
return indexQueries.stream() //
|
||||
.map(IndexQuery::getObject) //
|
||||
.map(entity -> (T) entityOperations.updateIndexedObject(
|
||||
@@ -593,7 +594,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
}
|
||||
|
||||
protected <T> SearchDocumentResponse.EntityCreator<T> getEntityCreator(ReadDocumentCallback<T> documentCallback) {
|
||||
return searchDocument -> CompletableFuture.completedFuture(documentCallback.doWith(searchDocument));
|
||||
return searchDocument -> CompletableFuture.<T> completedFuture(documentCallback.doWith(searchDocument));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -752,6 +753,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
|
||||
// region Document callbacks
|
||||
protected interface DocumentCallback<T> {
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
T doWith(@Nullable Document document);
|
||||
}
|
||||
@@ -815,6 +817,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
|
||||
@Override
|
||||
public SearchHits<T> doWith(SearchDocumentResponse response) {
|
||||
// noinspection NullableProblems,DataFlowIssue
|
||||
List<T> entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList());
|
||||
return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapHits(response, entities);
|
||||
}
|
||||
@@ -835,6 +838,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
|
||||
@Override
|
||||
public SearchScrollHits<T> doWith(SearchDocumentResponse response) {
|
||||
// noinspection DataFlowIssue,NullableProblems
|
||||
List<T> entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList());
|
||||
return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapScrollHits(response, entities);
|
||||
}
|
||||
|
||||
+2
-1
@@ -766,7 +766,8 @@ abstract public class AbstractReactiveElasticsearchTemplate
|
||||
/**
|
||||
* Value class to capture client independent information from a response to an index request.
|
||||
*/
|
||||
public record IndexResponseMetaData(String id, String index, long seqNo, long primaryTerm, long version) {
|
||||
public record IndexResponseMetaData(String id, String index, @Nullable Long seqNo, @Nullable Long primaryTerm,
|
||||
long version) {
|
||||
}
|
||||
// endregion
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
@@ -370,7 +369,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#initializeVersionProperty()
|
||||
*/
|
||||
@Override
|
||||
public @NonNull T initializeVersionProperty() {
|
||||
public T initializeVersionProperty() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -399,7 +398,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#incrementVersion()
|
||||
*/
|
||||
@Override
|
||||
public @NonNull T incrementVersion() {
|
||||
public T incrementVersion() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -408,7 +407,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getBean()
|
||||
*/
|
||||
@Override
|
||||
public @NonNull T getBean() {
|
||||
public T getBean() {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public interface IndexOperations {
|
||||
* @param settings the index settings
|
||||
* @return {@literal true} if the index was created
|
||||
*/
|
||||
boolean create(Map<String, Object> settings);
|
||||
boolean create(Map<String, @Nullable Object> settings);
|
||||
|
||||
/**
|
||||
* Create an index for given settings and mapping.
|
||||
@@ -62,7 +62,7 @@ public interface IndexOperations {
|
||||
* @return {@literal true} if the index was created
|
||||
* @since 4.2
|
||||
*/
|
||||
boolean create(Map<String, Object> settings, Document mapping);
|
||||
boolean create(Map<String, @Nullable Object> settings, Document mapping);
|
||||
|
||||
/**
|
||||
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
|
||||
@@ -142,7 +142,7 @@ public interface IndexOperations {
|
||||
*
|
||||
* @return the mapping
|
||||
*/
|
||||
Map<String, Object> getMapping();
|
||||
Map<String, @Nullable Object> getMapping();
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
+3
-3
@@ -46,12 +46,12 @@ public interface IndexOperationsAdapter extends IndexOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Map<String, Object> settings) {
|
||||
public boolean create(Map<String, @Nullable Object> settings) {
|
||||
return Boolean.TRUE.equals(reactiveIndexOperations.create(settings).block());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(Map<String, Object> settings, Document mapping) {
|
||||
public boolean create(Map<String, @Nullable Object> settings, Document mapping) {
|
||||
return Boolean.TRUE.equals(reactiveIndexOperations.create(settings, mapping).block());
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public interface IndexOperationsAdapter extends IndexOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMapping() {
|
||||
public Map<String, @Nullable Object> getMapping() {
|
||||
return Objects.requireNonNull(reactiveIndexOperations.getMapping().block());
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class MultiGetItem<T> {
|
||||
}
|
||||
|
||||
public static <T> MultiGetItem<T> of(@Nullable T item, @Nullable Failure failure) {
|
||||
return new MultiGetItem<>(item, failure);
|
||||
return new MultiGetItem(item, failure);
|
||||
}
|
||||
|
||||
public boolean hasItem() {
|
||||
|
||||
+3
-2
@@ -21,6 +21,7 @@ import reactor.core.publisher.Mono;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.index.*;
|
||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||
@@ -50,7 +51,7 @@ public interface ReactiveIndexOperations {
|
||||
* @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg.
|
||||
* the index already exist.
|
||||
*/
|
||||
Mono<Boolean> create(Map<String, Object> settings);
|
||||
Mono<Boolean> create(Map<String, @Nullable Object> settings);
|
||||
|
||||
/**
|
||||
* Create an index for given settings and mapping.
|
||||
@@ -61,7 +62,7 @@ public interface ReactiveIndexOperations {
|
||||
* the index already exist.
|
||||
* @since 4.2
|
||||
*/
|
||||
Mono<Boolean> create(Map<String, Object> settings, Document mapping);
|
||||
Mono<Boolean> create(Map<String, @Nullable Object> settings, Document mapping);
|
||||
|
||||
/**
|
||||
* Create an index with the settings and mapping defined for the entity this IndexOperations is bound to.
|
||||
|
||||
@@ -51,7 +51,7 @@ public class SearchHit<T> {
|
||||
private final Map<String, Double> matchedQueries = new LinkedHashMap<>();
|
||||
|
||||
public SearchHit(@Nullable String index, @Nullable String id, @Nullable String routing, float score,
|
||||
@Nullable Object[] sortValues, @Nullable Map<String, List<String>> highlightFields,
|
||||
Object @Nullable [] sortValues, @Nullable Map<String, List<String>> highlightFields,
|
||||
@Nullable Map<String, SearchHits<?>> innerHits, @Nullable NestedMetaData nestedMetaData,
|
||||
@Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries, T content) {
|
||||
this.index = index;
|
||||
@@ -193,7 +193,6 @@ public class SearchHit<T> {
|
||||
/**
|
||||
* @return the matched queries for this SearchHit.
|
||||
*/
|
||||
@Nullable
|
||||
public Map<String, Double> getMatchedQueries() {
|
||||
return matchedQueries;
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.data.core.ReactiveWrappers;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
import org.springframework.lang.Contract;
|
||||
|
||||
/**
|
||||
* Utility class with helper methods for working with {@link SearchHit}.
|
||||
@@ -47,6 +47,7 @@ public final class SearchHitSupport {
|
||||
* @return a corresponding object where the SearchHits are replaced by their content if possible, otherwise the
|
||||
* original object
|
||||
*/
|
||||
@Contract("null -> null; !null -> !null")
|
||||
@Nullable
|
||||
public static Object unwrapSearchHits(@Nullable Object result) {
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class SearchHitsImpl<T> implements SearchScrollHits<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchShardStatistics getSearchShardStatistics() {
|
||||
public @Nullable SearchShardStatistics getSearchShardStatistics() {
|
||||
return searchShardStatistics;
|
||||
}
|
||||
|
||||
|
||||
+15
-2
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* Interfaces and classes related to Elasticsearch cluster information and management.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.cluster;
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
* @author Christoph Strobl
|
||||
* @since 3.2
|
||||
*/
|
||||
public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, Object>> {
|
||||
public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, @Nullable Object>> {
|
||||
|
||||
String DEFAULT_TYPE_KEY = "_class";
|
||||
|
||||
@@ -47,7 +47,7 @@ public interface ElasticsearchTypeMapper extends TypeMapper<Map<String, Object>>
|
||||
@Nullable
|
||||
String getTypeKey();
|
||||
|
||||
default boolean containsTypeInformation(Map<String, Object> source) {
|
||||
default boolean containsTypeInformation(Map<String, @Nullable Object> source) {
|
||||
return readType(source) != null;
|
||||
}
|
||||
|
||||
|
||||
+11
-12
@@ -20,9 +20,9 @@ import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
@@ -167,7 +167,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJson<? extends Iterable<?>> convert(Map<String, Object> source) {
|
||||
public GeoJson<? extends Iterable<?>> convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
|
||||
@@ -206,7 +206,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonPoint convert(Map<String, Object> source) {
|
||||
public GeoJsonPoint convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonPoint.TYPE), "does not contain a type 'Point'");
|
||||
@@ -244,7 +244,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonMultiPoint convert(Map<String, Object> source) {
|
||||
public GeoJsonMultiPoint convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiPoint.TYPE), "does not contain a type 'MultiPoint'");
|
||||
@@ -279,7 +279,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonLineString convert(Map<String, Object> source) {
|
||||
public GeoJsonLineString convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonLineString.TYPE), "does not contain a type 'LineString'");
|
||||
@@ -311,7 +311,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonMultiLineString convert(Map<String, Object> source) {
|
||||
public GeoJsonMultiLineString convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiLineString.TYPE), "does not contain a type 'MultiLineString'");
|
||||
@@ -339,7 +339,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonPolygon convert(Map<String, Object> source) {
|
||||
public GeoJsonPolygon convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonPolygon.TYPE), "does not contain a type 'Polygon'");
|
||||
@@ -368,7 +368,6 @@ public class GeoConverters {
|
||||
|
||||
List<Object> coordinates = source.getCoordinates().stream() //
|
||||
.map(GeoJsonPolygonToMapConverter.INSTANCE::convert) //
|
||||
.filter(Objects::nonNull) //
|
||||
.map(it -> it.get("coordinates")) //
|
||||
.collect(Collectors.toList()); //
|
||||
map.put("coordinates", coordinates);
|
||||
@@ -383,7 +382,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonMultiPolygon convert(Map<String, Object> source) {
|
||||
public GeoJsonMultiPolygon convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonMultiPolygon.TYPE), "does not contain a type 'MultiPolygon'");
|
||||
@@ -430,7 +429,7 @@ public class GeoConverters {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public GeoJsonGeometryCollection convert(Map<String, Object> source) {
|
||||
public GeoJsonGeometryCollection convert(Map<String, @Nullable Object> source) {
|
||||
|
||||
String type = GeoConverters.getGeoJsonType(source);
|
||||
Assert.isTrue(type.equalsIgnoreCase(GeoJsonGeometryCollection.TYPE),
|
||||
@@ -448,7 +447,7 @@ public class GeoConverters {
|
||||
// endregion
|
||||
|
||||
// region helper functions
|
||||
private static String getGeoJsonType(Map<String, Object> source) {
|
||||
private static String getGeoJsonType(Map<String, @Nullable Object> source) {
|
||||
|
||||
Object type = source.get("type");
|
||||
Assert.notNull(type, "Document to convert does not contain a type");
|
||||
@@ -485,7 +484,7 @@ public class GeoConverters {
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<GeoJsonLineString> geoJsonLineStringsFromMap(Map<String, Object> source) {
|
||||
private static List<GeoJsonLineString> geoJsonLineStringsFromMap(Map<String, @Nullable Object> source) {
|
||||
Object coordinates = source.get("coordinates");
|
||||
Assert.notNull(coordinates, "Document to convert does not contain coordinates");
|
||||
Assert.isTrue(coordinates instanceof List, "coordinates must be a List");
|
||||
|
||||
+26
-34
@@ -24,7 +24,6 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -63,16 +62,7 @@ import org.springframework.data.mapping.Parameter;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.mapping.SimplePropertyHandler;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.CachingValueExpressionEvaluatorFactory;
|
||||
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
|
||||
import org.springframework.data.mapping.model.EntityInstantiator;
|
||||
import org.springframework.data.mapping.model.EntityInstantiators;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.data.mapping.model.ValueExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.ValueExpressionParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.*;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.format.datetime.DateFormatterRegistrar;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -267,7 +257,7 @@ public class MappingElasticsearchConverter
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings("unchecked")
|
||||
private <R> R read(TypeInformation<R> typeInformation, Map<String, Object> source) {
|
||||
private <R> R read(TypeInformation<R> typeInformation, Map<String, @Nullable Object> source) {
|
||||
|
||||
Assert.notNull(source, "Source must not be null!");
|
||||
|
||||
@@ -301,7 +291,7 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <R> R readMap(TypeInformation<?> type, Map<String, Object> source) {
|
||||
private <R> R readMap(TypeInformation<?> type, Map<String, @Nullable Object> source) {
|
||||
|
||||
Assert.notNull(source, "Document must not be null!");
|
||||
|
||||
@@ -313,9 +303,10 @@ public class MappingElasticsearchConverter
|
||||
Class<?> rawKeyType = keyType != null ? keyType.getType() : null;
|
||||
Class<?> rawValueType = valueType != null ? valueType.getType() : null;
|
||||
|
||||
Map<Object, Object> map = CollectionFactory.createMap(mapType, rawKeyType, source.keySet().size());
|
||||
Map<Object, @Nullable Object> map = (Map<Object, @Nullable Object>) CollectionFactory.createMap(mapType,
|
||||
rawKeyType, source.keySet().size());
|
||||
|
||||
for (Entry<String, Object> entry : source.entrySet()) {
|
||||
for (Entry<String, @Nullable Object> entry : source.entrySet()) {
|
||||
|
||||
if (typeMapper.isTypeKey(entry.getKey())) {
|
||||
continue;
|
||||
@@ -325,6 +316,7 @@ public class MappingElasticsearchConverter
|
||||
|
||||
if (rawKeyType != null && !rawKeyType.isAssignableFrom(key.getClass())) {
|
||||
key = conversionService.convert(key, rawKeyType);
|
||||
Assert.notNull(key, "converted key must not be null");
|
||||
}
|
||||
|
||||
Object value = entry.getValue();
|
||||
@@ -343,7 +335,7 @@ public class MappingElasticsearchConverter
|
||||
return (R) map;
|
||||
}
|
||||
|
||||
private <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String, Object> source) {
|
||||
private <R> R readEntity(ElasticsearchPersistentEntity<?> entity, Map<String, @Nullable Object> source) {
|
||||
|
||||
ElasticsearchPersistentEntity<?> targetEntity = computeClosestEntity(entity, source);
|
||||
ValueExpressionEvaluator evaluator = expressionEvaluatorFactory.create(source);
|
||||
@@ -582,7 +574,7 @@ public class MappingElasticsearchConverter
|
||||
: TypeInformation.OBJECT;
|
||||
Class<?> rawComponentType = componentType.getType();
|
||||
|
||||
Collection<Object> items = targetType.getType().isArray() //
|
||||
Collection<@Nullable Object> items = targetType.getType().isArray() //
|
||||
? new ArrayList<>(source.size()) //
|
||||
: CollectionFactory.createCollection(collectionType, rawComponentType, source.size());
|
||||
|
||||
@@ -672,7 +664,7 @@ public class MappingElasticsearchConverter
|
||||
*/
|
||||
private <T> void populateScriptedFields(ElasticsearchPersistentEntity<?> entity, T result,
|
||||
SearchDocument searchDocument) {
|
||||
Map<String, List<Object>> fields = searchDocument.getFields();
|
||||
Map<String, List<@Nullable Object>> fields = searchDocument.getFields();
|
||||
entity.doWithProperties((SimplePropertyHandler) property -> {
|
||||
if (property.isAnnotationPresent(ScriptedField.class)) {
|
||||
ScriptedField scriptedField = property.findAnnotation(ScriptedField.class);
|
||||
@@ -695,7 +687,7 @@ public class MappingElasticsearchConverter
|
||||
* Compute the type to use by checking the given entity against the store type;
|
||||
*/
|
||||
private ElasticsearchPersistentEntity<?> computeClosestEntity(ElasticsearchPersistentEntity<?> entity,
|
||||
Map<String, Object> source) {
|
||||
Map<String, @Nullable Object> source) {
|
||||
|
||||
TypeInformation<?> typeToUse = typeMapper.readType(source);
|
||||
|
||||
@@ -770,7 +762,7 @@ public class MappingElasticsearchConverter
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public <T> T getParameterValue(Parameter<T, ElasticsearchPersistentProperty> parameter) {
|
||||
public <T> @Nullable T getParameterValue(Parameter<T, ElasticsearchPersistentProperty> parameter) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -822,7 +814,7 @@ public class MappingElasticsearchConverter
|
||||
* @param typeInformation type information for the source
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void writeInternal(@Nullable Object source, Map<String, Object> sink,
|
||||
private void writeInternal(@Nullable Object source, Map<String, @Nullable Object> sink,
|
||||
@Nullable TypeInformation<?> typeInformation) {
|
||||
|
||||
if (null == source) {
|
||||
@@ -833,7 +825,7 @@ public class MappingElasticsearchConverter
|
||||
Optional<Class<?>> customTarget = conversions.getCustomWriteTarget(entityType, Map.class);
|
||||
|
||||
if (customTarget.isPresent()) {
|
||||
Map<String, Object> result = conversionService.convert(source, Map.class);
|
||||
Map<String, @Nullable Object> result = conversionService.convert(source, Map.class);
|
||||
|
||||
if (result != null) {
|
||||
sink.putAll(result);
|
||||
@@ -863,7 +855,7 @@ public class MappingElasticsearchConverter
|
||||
* @param sink the destination
|
||||
* @param entity entity for the source
|
||||
*/
|
||||
private void writeInternal(@Nullable Object source, Map<String, Object> sink,
|
||||
private void writeInternal(@Nullable Object source, Map<String, @Nullable Object> sink,
|
||||
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||
|
||||
if (source == null) {
|
||||
@@ -905,7 +897,7 @@ public class MappingElasticsearchConverter
|
||||
* @param sink must not be {@literal null}.
|
||||
* @param propertyType must not be {@literal null}.
|
||||
*/
|
||||
private Map<String, Object> writeMapInternal(Map<?, ?> source, Map<String, Object> sink,
|
||||
private Map<String, @Nullable Object> writeMapInternal(Map<?, ?> source, Map<String, @Nullable Object> sink,
|
||||
TypeInformation<?> propertyType) {
|
||||
|
||||
for (Map.Entry<?, ?> entry : source.entrySet()) {
|
||||
@@ -922,7 +914,7 @@ public class MappingElasticsearchConverter
|
||||
sink.put(simpleKey,
|
||||
writeCollectionInternal(asCollection(value), propertyType.getMapValueType(), new ArrayList<>()));
|
||||
} else {
|
||||
Map<String, Object> document = Document.create();
|
||||
Map<String, @Nullable Object> document = Document.create();
|
||||
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType()
|
||||
: TypeInformation.OBJECT;
|
||||
writeInternal(value, document, valueTypeInfo);
|
||||
@@ -966,7 +958,7 @@ public class MappingElasticsearchConverter
|
||||
} else if (element instanceof Collection || elementType.isArray()) {
|
||||
collection.add(writeCollectionInternal(asCollection(element), componentType, new ArrayList<>()));
|
||||
} else {
|
||||
Map<String, Object> document = Document.create();
|
||||
Map<String, @Nullable Object> document = Document.create();
|
||||
writeInternal(element, document, componentType);
|
||||
collection.add(document);
|
||||
}
|
||||
@@ -1080,7 +1072,7 @@ public class MappingElasticsearchConverter
|
||||
: mappingContext.getRequiredPersistentEntity(type);
|
||||
|
||||
Object existingValue = sink.get(property);
|
||||
Map<String, Object> document = existingValue instanceof Map ? (Map<String, Object>) existingValue
|
||||
Map<String, @Nullable Object> document = existingValue instanceof Map ? (Map<String, Object>) existingValue
|
||||
: Document.create();
|
||||
|
||||
addCustomTypeKeyIfNecessary(value, document, TypeInformation.of(property.getRawType()));
|
||||
@@ -1097,7 +1089,7 @@ public class MappingElasticsearchConverter
|
||||
* @param sink must not be {@literal null}.
|
||||
* @param type type to compare to
|
||||
*/
|
||||
private void addCustomTypeKeyIfNecessary(Object source, Map<String, Object> sink,
|
||||
private void addCustomTypeKeyIfNecessary(Object source, Map<String, @Nullable Object> sink,
|
||||
@Nullable TypeInformation<?> type) {
|
||||
|
||||
if (!writeTypeHints) {
|
||||
@@ -1218,7 +1210,7 @@ public class MappingElasticsearchConverter
|
||||
Assert.notNull(map, "Given map must not be null!");
|
||||
Assert.notNull(property, "PersistentProperty must not be null!");
|
||||
|
||||
return writeMapInternal(map, new LinkedHashMap<>(map.size()), property.getTypeInformation());
|
||||
return writeMapInternal(map, new LinkedHashMap(map.size()), property.getTypeInformation());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1492,9 +1484,9 @@ public class MappingElasticsearchConverter
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
static class MapValueAccessor {
|
||||
|
||||
final Map<String, Object> target;
|
||||
final Map<String, @Nullable Object> target;
|
||||
|
||||
MapValueAccessor(Map<String, Object> target) {
|
||||
MapValueAccessor(Map<String, @Nullable Object> target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -1528,7 +1520,7 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
Iterator<String> parts = Arrays.asList(fieldName.split("\\.")).iterator();
|
||||
Map<String, Object> source = target;
|
||||
Map<String, @Nullable Object> source = target;
|
||||
Object result = null;
|
||||
|
||||
while (parts.hasNext()) {
|
||||
@@ -1559,11 +1551,11 @@ public class MappingElasticsearchConverter
|
||||
target.put(property.getFieldName(), value);
|
||||
}
|
||||
|
||||
private Map<String, Object> getAsMap(Object result) {
|
||||
private Map<String, @Nullable Object> getAsMap(Object result) {
|
||||
|
||||
if (result instanceof Map) {
|
||||
// noinspection unchecked
|
||||
return (Map<String, Object>) result;
|
||||
return (Map<String, @Nullable Object>) result;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("%s is not a Map.", result));
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class Explanation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
@@ -81,7 +81,7 @@ public class Explanation {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (match ? 1 : 0);
|
||||
int result = (Boolean.TRUE.equals(match) ? 1 : 0);
|
||||
result = 31 * result + value.hashCode();
|
||||
result = 31 * result + (description != null ? description.hashCode() : 0);
|
||||
result = 31 * result + details.hashCode();
|
||||
|
||||
@@ -215,7 +215,7 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#containsKey(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
public boolean containsKey(@Nullable Object key) {
|
||||
return documentAsMap.containsKey(key);
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#containsValue(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
public boolean containsValue(@Nullable Object value) {
|
||||
return documentAsMap.containsValue(value);
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#get(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
public Object get(@Nullable Object key) {
|
||||
return documentAsMap.get(key);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ class MapDocument implements Document {
|
||||
* @see java.lang.Object#getOrDefault(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object getOrDefault(Object key, Object defaultValue) {
|
||||
public Object getOrDefault(@Nullable Object key, @Nullable Object defaultValue) {
|
||||
return documentAsMap.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object put(String key, Object value) {
|
||||
public Object put(String key, @Nullable Object value) {
|
||||
return documentAsMap.put(key, value);
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#remove(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
public Object remove(@Nullable Object key) {
|
||||
return documentAsMap.remove(key);
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ class MapDocument implements Document {
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
return documentAsMap.equals(o);
|
||||
}
|
||||
|
||||
@@ -332,7 +332,8 @@ class MapDocument implements Document {
|
||||
* @see java.util.Map#forEach(java.util.function.BiConsumer)
|
||||
*/
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super String, ? super Object> action) {
|
||||
public void forEach(
|
||||
@SuppressWarnings("NullableProblems") BiConsumer<? super String, ? super @Nullable Object> action) {
|
||||
documentAsMap.forEach(action);
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -41,7 +41,7 @@ public interface SearchDocument extends Document {
|
||||
/**
|
||||
* @return the fields for the search result, not {@literal null}
|
||||
*/
|
||||
Map<String, List<Object>> getFields();
|
||||
Map<String, List<@Nullable Object>> getFields();
|
||||
|
||||
/**
|
||||
* The first value of the given field.
|
||||
@@ -50,7 +50,7 @@ public interface SearchDocument extends Document {
|
||||
*/
|
||||
@Nullable
|
||||
default <V> V getFieldValue(final String name) {
|
||||
List<Object> values = getFields().get(name);
|
||||
List<@Nullable Object> values = getFields().get(name);
|
||||
if (values == null || values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public interface SearchDocument extends Document {
|
||||
*/
|
||||
@Nullable
|
||||
default <V> List<V> getFieldValues(final String name) {
|
||||
List<Object> values = getFields().get(name);
|
||||
List<@Nullable Object> values = getFields().get(name);
|
||||
if (values == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -74,8 +74,7 @@ public interface SearchDocument extends Document {
|
||||
/**
|
||||
* @return the sort values for the search hit
|
||||
*/
|
||||
@Nullable
|
||||
default Object[] getSortValues() {
|
||||
default Object @Nullable [] getSortValues() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+17
-15
@@ -35,7 +35,7 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
|
||||
private final float score;
|
||||
private final Object[] sortValues;
|
||||
private final Map<String, List<Object>> fields = new HashMap<>();
|
||||
private final Map<String, List<@Nullable Object>> fields = new HashMap<>();
|
||||
private final Document delegate;
|
||||
private final Map<String, List<String>> highlightFields = new HashMap<>();
|
||||
private final Map<String, SearchDocumentResponse> innerHits = new HashMap<>();
|
||||
@@ -44,9 +44,11 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
@Nullable private final Map<String, Double> matchedQueries;
|
||||
@Nullable private final String routing;
|
||||
|
||||
public SearchDocumentAdapter(Document delegate, float score, Object[] sortValues, Map<String, List<Object>> fields,
|
||||
public SearchDocumentAdapter(Document delegate, float score, Object[] sortValues,
|
||||
Map<String, List<@Nullable Object>> fields,
|
||||
Map<String, List<String>> highlightFields, Map<String, SearchDocumentResponse> innerHits,
|
||||
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation, @Nullable Map<String, Double> matchedQueries,
|
||||
@Nullable NestedMetaData nestedMetaData, @Nullable Explanation explanation,
|
||||
@Nullable Map<String, Double> matchedQueries,
|
||||
@Nullable String routing) {
|
||||
|
||||
this.delegate = delegate;
|
||||
@@ -74,7 +76,7 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<Object>> getFields() {
|
||||
public Map<String, List<@Nullable Object>> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
@@ -186,17 +188,17 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
public boolean containsKey(@Nullable Object key) {
|
||||
return delegate.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
public boolean containsValue(@Nullable Object value) {
|
||||
return delegate.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
public Object get(@Nullable Object key) {
|
||||
|
||||
if (delegate.containsKey(key)) {
|
||||
return delegate.get(key);
|
||||
@@ -207,12 +209,12 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(String key, Object value) {
|
||||
public @Nullable Object put(String key, @Nullable Object value) {
|
||||
return delegate.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
public Object remove(@Nullable Object key) {
|
||||
return delegate.remove(key);
|
||||
}
|
||||
|
||||
@@ -232,12 +234,12 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
public Collection<@Nullable Object> values() {
|
||||
return delegate.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
public Set<Entry<String, @Nullable Object>> entrySet() {
|
||||
return delegate.entrySet();
|
||||
}
|
||||
|
||||
@@ -254,7 +256,7 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
@@ -270,17 +272,17 @@ public class SearchDocumentAdapter implements SearchDocument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(BiConsumer<? super String, ? super Object> action) {
|
||||
public void forEach(@Nullable BiConsumer<? super String, ? super @Nullable Object> action) {
|
||||
delegate.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key, Object value) {
|
||||
public boolean remove(@Nullable Object key, @Nullable Object value) {
|
||||
return delegate.remove(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRouting() {
|
||||
public @Nullable String getRouting() {
|
||||
return routing;
|
||||
}
|
||||
|
||||
|
||||
+15
-2
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* Classes related to the Document structure of Elasticsearch documents and search responses.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.document;
|
||||
|
||||
+3
-2
@@ -31,10 +31,11 @@ import org.springframework.data.mapping.callback.EntityCallback;
|
||||
public interface AfterLoadCallback<T> extends EntityCallback<Document> {
|
||||
|
||||
/**
|
||||
* Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the
|
||||
* same or a modified instance of the {@link Document} object.
|
||||
* Entity callback method invoked after a {@link Document} is read from Elasticsearch. Can return either the same or a
|
||||
* modified instance of the {@link Document} object.
|
||||
*
|
||||
* @param document the document.
|
||||
* @param type the type into which the document will be converted
|
||||
* @param indexCoordinates of the index the document was read from.
|
||||
* @return a possible modified or new {@link Document}.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* classes and interfaces related to Spring Data Elasticsearch events and callbacks.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.event;
|
||||
|
||||
@@ -8,18 +8,27 @@ import tools.jackson.databind.SerializationContext;
|
||||
import tools.jackson.databind.ValueDeserializer;
|
||||
import tools.jackson.databind.ValueSerializer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class PointSerializer extends ValueSerializer<Point> {
|
||||
@Override
|
||||
public void serialize(Point value, JsonGenerator gen, SerializationContext serializers) throws JacksonException {
|
||||
public void serialize(Point value, @Nullable JsonGenerator gen, @Nullable SerializationContext serializers)
|
||||
throws JacksonException {
|
||||
|
||||
Assert.notNull(gen, "gen must not be null");
|
||||
|
||||
gen.writePOJO(GeoPoint.fromPoint(value));
|
||||
}
|
||||
}
|
||||
|
||||
class PointDeserializer extends ValueDeserializer<Point> {
|
||||
@Override
|
||||
public Point deserialize(JsonParser p, DeserializationContext context) throws JacksonException {
|
||||
public Point deserialize(@Nullable JsonParser p, @Nullable DeserializationContext context) throws JacksonException {
|
||||
|
||||
Assert.notNull(p, "p must not be null");
|
||||
|
||||
return GeoPoint.toPoint(p.readValueAs(GeoPoint.class));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -68,7 +69,7 @@ public class GeoJsonGeometryCollection implements GeoJson<Iterable<GeoJson<?>>>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -122,7 +123,7 @@ public class GeoJsonLineString implements GeoJson<Iterable<Point>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -81,7 +82,7 @@ public class GeoJsonMultiLineString implements GeoJson<Iterable<GeoJsonLineStrin
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -122,7 +123,7 @@ public class GeoJsonMultiPoint implements GeoJson<Iterable<Point>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -62,7 +63,7 @@ public class GeoJsonMultiPolygon implements GeoJson<Iterable<GeoJsonPolygon>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core.geo;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
/**
|
||||
@@ -89,7 +90,7 @@ public class GeoJsonPoint implements GeoJson<List<Double>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -207,7 +208,7 @@ public class GeoJsonPolygon implements GeoJson<Iterable<GeoJsonLineString>> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.geo;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.geo.Point;
|
||||
|
||||
/**
|
||||
@@ -63,7 +64,7 @@ public class GeoPoint {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.geo;
|
||||
|
||||
+3
-3
@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class AliasActionParameters {
|
||||
private final String[] indices;
|
||||
@Nullable private final String[] aliases;
|
||||
private final String @Nullable [] aliases;
|
||||
@Nullable private final Query filterQuery;
|
||||
@Nullable private final Class<?> filterQueryClass;
|
||||
@Nullable private final Boolean isHidden;
|
||||
@@ -36,7 +36,7 @@ public class AliasActionParameters {
|
||||
@Nullable private final String indexRouting;
|
||||
@Nullable private final String searchRouting;
|
||||
|
||||
private AliasActionParameters(String[] indices, @Nullable String[] aliases, @Nullable Boolean isHidden,
|
||||
private AliasActionParameters(String[] indices, String @Nullable [] aliases, @Nullable Boolean isHidden,
|
||||
@Nullable Boolean isWriteIndex, @Nullable String routing, @Nullable String indexRouting,
|
||||
@Nullable String searchRouting, @Nullable Query filterQuery, @Nullable Class<?> filterQueryClass) {
|
||||
this.indices = indices;
|
||||
@@ -66,7 +66,7 @@ public class AliasActionParameters {
|
||||
return indices;
|
||||
}
|
||||
|
||||
public String@Nullable[] getAliases() {
|
||||
public String @Nullable [] getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AliasActions {
|
||||
*
|
||||
* @param actions {@link AliasAction} elements
|
||||
*/
|
||||
public AliasActions(@Nullable AliasAction... actions) {
|
||||
public AliasActions(AliasAction @Nullable... actions) {
|
||||
add(actions);
|
||||
}
|
||||
|
||||
@@ -52,10 +52,9 @@ public class AliasActions {
|
||||
* @param actions elements to add
|
||||
* @return this object
|
||||
*/
|
||||
public AliasActions add(@Nullable AliasAction... actions) {
|
||||
public AliasActions add(AliasAction @Nullable... actions) {
|
||||
|
||||
if (actions != null) {
|
||||
// noinspection NullableProblems
|
||||
this.actions.addAll(Arrays.asList(actions));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public record ComponentTemplateRequestData(@Nullable Settings settings, @Nullabl
|
||||
@Nullable private AliasActions aliasActions;
|
||||
@Nullable private Boolean allowAutoCreate;
|
||||
|
||||
public Builder withSettings(Map<String, Object> settings) {
|
||||
public Builder withSettings(Map<String, @Nullable Object> settings) {
|
||||
this.settings = new Settings(settings);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.core.TypeInformation;
|
||||
@@ -112,9 +110,15 @@ public class MappingBuilder {
|
||||
|
||||
protected final ElasticsearchConverter elasticsearchConverter;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final MappingParametersCustomizer customizer;
|
||||
|
||||
public MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
|
||||
this(elasticsearchConverter, MappingParameters::from);
|
||||
}
|
||||
|
||||
public MappingBuilder(ElasticsearchConverter elasticsearchConverter, MappingParametersCustomizer customizer) {
|
||||
this.elasticsearchConverter = elasticsearchConverter;
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,7 +279,7 @@ public class MappingBuilder {
|
||||
writeTypeHintMapping(propertiesNode);
|
||||
|
||||
if (entity != null) {
|
||||
entity.doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
|
||||
entity.doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
|
||||
try {
|
||||
if (property.isAnnotationPresent(Transient.class) || isInIgnoreFields(property, parentFieldAnnotation)) {
|
||||
return;
|
||||
@@ -589,7 +593,7 @@ public class MappingBuilder {
|
||||
private void addFieldMappingParameters(ObjectNode fieldNode, Annotation annotation, boolean nestedOrObjectField)
|
||||
throws IOException {
|
||||
|
||||
MappingParameters mappingParameters = MappingParameters.from(annotation);
|
||||
MappingParameters mappingParameters = customizer.from(annotation);
|
||||
|
||||
if (!nestedOrObjectField && mappingParameters.isStore()) {
|
||||
fieldNode.put(FIELD_PARAM_STORE, true);
|
||||
|
||||
+136
-5
@@ -34,7 +34,9 @@ import org.springframework.util.StringUtils;
|
||||
/**
|
||||
* A class to hold the mapping parameters that might be set on
|
||||
* {@link org.springframework.data.elasticsearch.annotations.Field } or
|
||||
* {@link org.springframework.data.elasticsearch.annotations.InnerField} annotation.
|
||||
* {@link org.springframework.data.elasticsearch.annotations.InnerField} annotation. The class allows extensibility
|
||||
* (non-final) to simplify mapping parameters customization, provided by
|
||||
* {@link org.springframework.data.elasticsearch.core.index.MappingParametersCustomizer}.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Aleksei Arsenev
|
||||
@@ -42,9 +44,10 @@ import org.springframework.util.StringUtils;
|
||||
* @author Morgan Lutz
|
||||
* @author Sascha Woo
|
||||
* @author Haibo Liu
|
||||
* @author Andriy Redko
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class MappingParameters {
|
||||
public class MappingParameters {
|
||||
|
||||
static final String FIELD_PARAM_COERCE = "coerce";
|
||||
static final String FIELD_PARAM_COPY_TO = "copy_to";
|
||||
@@ -86,7 +89,7 @@ public final class MappingParameters {
|
||||
|
||||
private final String analyzer;
|
||||
private final boolean coerce;
|
||||
@Nullable private final String[] copyTo;
|
||||
private final String @Nullable [] copyTo;
|
||||
private final DateFormat[] dateFormats;
|
||||
private final String[] dateFormatPatterns;
|
||||
private final boolean docValues;
|
||||
@@ -137,7 +140,7 @@ public final class MappingParameters {
|
||||
}
|
||||
}
|
||||
|
||||
private MappingParameters(Field field) {
|
||||
protected MappingParameters(Field field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
@@ -184,7 +187,7 @@ public final class MappingParameters {
|
||||
eagerGlobalOrdinals = field.eagerGlobalOrdinals();
|
||||
}
|
||||
|
||||
private MappingParameters(InnerField field) {
|
||||
protected MappingParameters(InnerField field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
@@ -417,4 +420,132 @@ public final class MappingParameters {
|
||||
objectNode.put(FIELD_PARAM_EAGER_GLOBAL_ORDINALS, eagerGlobalOrdinals);
|
||||
}
|
||||
}
|
||||
|
||||
protected String analyzer() {
|
||||
return analyzer;
|
||||
}
|
||||
|
||||
protected boolean coerce() {
|
||||
return coerce;
|
||||
}
|
||||
|
||||
protected String @Nullable [] copyTo() {
|
||||
return copyTo;
|
||||
}
|
||||
|
||||
protected DateFormat[] dateFormats() {
|
||||
return dateFormats;
|
||||
}
|
||||
|
||||
protected String[] dateFormatPatterns() {
|
||||
return dateFormatPatterns;
|
||||
}
|
||||
|
||||
protected boolean hasDocValues() {
|
||||
return docValues;
|
||||
}
|
||||
|
||||
protected boolean hasEagerGlobalOrdinals() {
|
||||
return eagerGlobalOrdinals;
|
||||
}
|
||||
|
||||
protected boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
protected boolean hasFielddata() {
|
||||
return fielddata;
|
||||
}
|
||||
|
||||
protected Integer ignoreAbove() {
|
||||
return ignoreAbove;
|
||||
}
|
||||
|
||||
protected boolean isIgnoreMalformed() {
|
||||
return ignoreMalformed;
|
||||
}
|
||||
|
||||
protected boolean isIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
protected IndexOptions indexOptions() {
|
||||
return indexOptions;
|
||||
}
|
||||
|
||||
protected boolean isIndexPhrases() {
|
||||
return indexPhrases;
|
||||
}
|
||||
|
||||
protected IndexPrefixes indexPrefixes() {
|
||||
return indexPrefixes;
|
||||
}
|
||||
|
||||
protected String normalizer() {
|
||||
return normalizer;
|
||||
}
|
||||
|
||||
protected boolean hasNorms() {
|
||||
return norms;
|
||||
}
|
||||
|
||||
protected Integer maxShingleSize() {
|
||||
return maxShingleSize;
|
||||
}
|
||||
|
||||
protected String nullValue() {
|
||||
return nullValue;
|
||||
}
|
||||
|
||||
protected NullValueType nullValueType() {
|
||||
return nullValueType;
|
||||
}
|
||||
|
||||
protected Integer positionIncrementGap() {
|
||||
return positionIncrementGap;
|
||||
}
|
||||
|
||||
protected boolean positiveScoreImpact() {
|
||||
return positiveScoreImpact;
|
||||
}
|
||||
|
||||
protected Integer dims() {
|
||||
return dims;
|
||||
}
|
||||
|
||||
protected String elementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
protected KnnSimilarity knnSimilarity() {
|
||||
return knnSimilarity;
|
||||
}
|
||||
|
||||
protected KnnIndexOptions knnIndexOptions() {
|
||||
return knnIndexOptions;
|
||||
}
|
||||
|
||||
protected String searchAnalyzer() {
|
||||
return searchAnalyzer;
|
||||
}
|
||||
|
||||
protected double scalingFactor() {
|
||||
return scalingFactor;
|
||||
}
|
||||
|
||||
protected String similarity() {
|
||||
return similarity;
|
||||
}
|
||||
|
||||
protected TermVector termVector() {
|
||||
return termVector;
|
||||
}
|
||||
|
||||
protected FieldType type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
protected String mappedTypeName() {
|
||||
return mappedTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2026-present 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.core.index;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* Allows to customize {@link org.springframework.data.elasticsearch.core.index.MappingParameters} that are being
|
||||
* emitted for each supported annotation. Needed by dependent projects like Spring-Data-Opensearch.
|
||||
*
|
||||
* @author Andriy Redko
|
||||
* @since 6.1.0
|
||||
*/
|
||||
public interface MappingParametersCustomizer {
|
||||
/**
|
||||
* Customize @link org.springframework.data.elasticsearch.core.index.MappingParameters} for each supported annotation.
|
||||
*
|
||||
* @param annotation supported annotation
|
||||
* @return customized @link org.springframework.data.elasticsearch.core.index.MappingParameters}
|
||||
*/
|
||||
|
||||
MappingParameters from(Annotation annotation);
|
||||
}
|
||||
+1
-1
@@ -102,7 +102,7 @@ public class PutTemplateRequest {
|
||||
this.indexPatterns = indexPatterns;
|
||||
}
|
||||
|
||||
public TemplateRequestBuilder withSettings(Map<String, Object> settings) {
|
||||
public TemplateRequestBuilder withSettings(Map<String, @Nullable Object> settings) {
|
||||
this.settings = new Settings(settings);
|
||||
return this;
|
||||
}
|
||||
|
||||
+5
@@ -31,6 +31,7 @@ import org.springframework.data.mapping.MappingException;
|
||||
* Subclass of {@link MappingBuilder} with specialized methods To inhibit blocking calls
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Andriy Redko
|
||||
* @since 4.3
|
||||
*/
|
||||
public class ReactiveMappingBuilder extends MappingBuilder {
|
||||
@@ -39,6 +40,10 @@ public class ReactiveMappingBuilder extends MappingBuilder {
|
||||
super(elasticsearchConverter);
|
||||
}
|
||||
|
||||
public ReactiveMappingBuilder(ElasticsearchConverter elasticsearchConverter, MappingParametersCustomizer customizer) {
|
||||
super(elasticsearchConverter, customizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildPropertyMapping(Class<?> clazz) throws MappingException {
|
||||
throw new UnsupportedOperationException(
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.support.DefaultStringObjectMap;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class Settings extends DefaultStringObjectMap<Settings> {
|
||||
|
||||
public Settings() {}
|
||||
|
||||
public Settings(Map<String, Object> map) {
|
||||
public Settings(Map<String, @Nullable Object> map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ public class Settings extends DefaultStringObjectMap<Settings> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
public Object get(@Nullable Object key) {
|
||||
return containsKey(key) ? super.get(key) : path(key.toString());
|
||||
}
|
||||
|
||||
@@ -75,11 +76,11 @@ public class Settings extends DefaultStringObjectMap<Settings> {
|
||||
* taken from https://stackoverflow.com/a/29698326/4393565
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<?, ?> deepMerge(Map<String, Object> original, Map<String, Object> newMap) {
|
||||
private static Map<?, ?> deepMerge(Map<String, @Nullable Object> original, Map<String, @Nullable Object> newMap) {
|
||||
for (Object key : newMap.keySet()) {
|
||||
if (newMap.get(key) instanceof Map && original.get(key) instanceof Map) {
|
||||
Map<String, Object> originalChild = (Map<String, Object>) original.get(key);
|
||||
Map<String, Object> newChild = (Map<String, Object>) newMap.get(key);
|
||||
Map<String, @Nullable Object> originalChild = (Map<String, Object>) original.get(key);
|
||||
Map<String, @Nullable Object> newChild = (Map<String, Object>) newMap.get(key);
|
||||
original.put(key.toString(), deepMerge(originalChild, newChild));
|
||||
} else if (newMap.get(key) instanceof List && original.get(key) instanceof List) {
|
||||
List<Object> originalChild = (List<Object>) original.get(key);
|
||||
@@ -112,9 +113,9 @@ public class Settings extends DefaultStringObjectMap<Settings> {
|
||||
* flattens a Map<String, Object> to a stream of Map.Entry objects where the keys are the dot separated concatenated
|
||||
* keys of sub map entries
|
||||
*/
|
||||
static private Stream<Map.Entry<String, Object>> doFlatten(Map.Entry<String, Object> entry) {
|
||||
static private Stream<Map.Entry<String, @Nullable Object>> doFlatten(Map.Entry<String, @Nullable Object> entry) {
|
||||
|
||||
if (entry.getValue()instanceof Map<?, ?> nested) {
|
||||
if (entry.getValue() instanceof Map<?, ?> nested) {
|
||||
|
||||
// noinspection unchecked
|
||||
return nested.entrySet().stream() //
|
||||
|
||||
@@ -91,7 +91,7 @@ public class TemplateData {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateDataBuilder withSettings(Map<String, Object> settings) {
|
||||
public TemplateDataBuilder withSettings(Map<String, @Nullable Object> settings) {
|
||||
this.settings = new Settings(settings);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* Classes related to Elasticsearch index management.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.index;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class JoinField<ID> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.join;
|
||||
@@ -115,7 +115,7 @@ public class Alias {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof Alias that))
|
||||
|
||||
+4
-4
@@ -33,7 +33,7 @@ public class CreateIndexSettings {
|
||||
private final IndexCoordinates indexCoordinates;
|
||||
private final Set<Alias> aliases;
|
||||
|
||||
@Nullable private final Map<String, Object> settings;
|
||||
@Nullable private final Map<String, @Nullable Object> settings;
|
||||
|
||||
@Nullable private final Document mapping;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class CreateIndexSettings {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<String, Object> getSettings() {
|
||||
public Map<String, @Nullable Object> getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class CreateIndexSettings {
|
||||
private final IndexCoordinates indexCoordinates;
|
||||
private final Set<Alias> aliases = new HashSet<>();
|
||||
|
||||
@Nullable private Map<String, Object> settings;
|
||||
@Nullable private Map<String, @Nullable Object> settings;
|
||||
|
||||
@Nullable private Document mapping;
|
||||
|
||||
@@ -94,7 +94,7 @@ public class CreateIndexSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withSettings(Map<String, Object> settings) {
|
||||
public Builder withSettings(Map<String, @Nullable Object> settings) {
|
||||
Assert.notNull(settings, "settings must not be null");
|
||||
this.settings = settings;
|
||||
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core.mapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ public class IndexCoordinates {
|
||||
* @since 4.2
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
+3
-5
@@ -23,9 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.core.TypeInformation;
|
||||
@@ -263,6 +261,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
throw new MappingException("@IndexedIndexName annotation must be put on String property");
|
||||
}
|
||||
|
||||
// noinspection VariableNotUsedInsideIf
|
||||
if (indexedIndexNameProperty != null) {
|
||||
throw new MappingException(
|
||||
"@IndexedIndexName annotation can only be put on one property in an entity");
|
||||
@@ -301,7 +300,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
|
||||
return fieldNamePropertyCache.computeIfAbsent(fieldName, key -> {
|
||||
AtomicReference<@Nullable ElasticsearchPersistentProperty> propertyRef = new AtomicReference<>();
|
||||
doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
|
||||
doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
|
||||
if (key.equals(property.getFieldName())) {
|
||||
propertyRef.set(property);
|
||||
}
|
||||
@@ -425,8 +424,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
|
||||
try {
|
||||
Expression expression = routingExpressions.computeIfAbsent(routing, PARSER::parseExpression);
|
||||
ExpressionDependencies expressionDependencies = expression != null ? ExpressionDependencies.discover(expression)
|
||||
: ExpressionDependencies.none();
|
||||
ExpressionDependencies expressionDependencies = ExpressionDependencies.discover(expression);
|
||||
|
||||
EvaluationContext context = getEvaluationContext(null, expressionDependencies);
|
||||
context.setVariable("entity", bean);
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.mapping;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
@@ -602,6 +602,7 @@ public class BaseQuery implements Query {
|
||||
// searchForStream to work correctly (#3098) as there the page size defines what is
|
||||
// returned in a single request, and the max result determines the total number of
|
||||
// documents returned.
|
||||
// noinspection DataFlowIssue maxResults is not null here, this is checked with isLimiting()
|
||||
requestSize = Math.min(pageable.getPageSize(), getMaxResults());
|
||||
}
|
||||
} else if (pageable == UNSET_PAGE) {
|
||||
@@ -622,6 +623,7 @@ public class BaseQuery implements Query {
|
||||
// searchForStream to work correctly (#3098) as there the page size defines what is
|
||||
// returned in a single request, and the max result determines the total number of
|
||||
// documents returned.
|
||||
// noinspection DataFlowIssue maxResults is not null here, this is checked with isLimiting()
|
||||
requestSize = Math.min(INDEX_MAX_RESULT_WINDOW, getMaxResults());
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -97,7 +97,6 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
return maxResults;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Collection<String> getIds() {
|
||||
return ids;
|
||||
}
|
||||
@@ -182,7 +181,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
* @since 6.1
|
||||
*/
|
||||
@Nullable
|
||||
public Boolean getIncludeNamedQueriesScore(){
|
||||
public Boolean getIncludeNamedQueriesScore() {
|
||||
return includeNamedQueryScore;
|
||||
}
|
||||
|
||||
@@ -393,7 +392,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
/**
|
||||
* @since 6.1
|
||||
*/
|
||||
public SELF withIncludeNamedQueryScore (@Nullable Boolean namedQueryScore) {
|
||||
public SELF withIncludeNamedQueryScore(@Nullable Boolean namedQueryScore) {
|
||||
this.includeNamedQueryScore = namedQueryScore;
|
||||
return self();
|
||||
}
|
||||
|
||||
@@ -61,16 +61,16 @@ public class Criteria {
|
||||
private float boost = Float.NaN;
|
||||
private boolean negating = false;
|
||||
|
||||
// we cash this and recalculate when properties used in equals change
|
||||
// see https://github.com/spring-projects/spring-data-elasticsearch/issues/3083
|
||||
private int hashCode;
|
||||
// we cache this and recalculate when properties used in equals change
|
||||
// see https://github.com/spring-projects/spring-data-elasticsearch/issues/3083
|
||||
private int hashCode;
|
||||
|
||||
private final CriteriaChain criteriaChain = new CriteriaChain();
|
||||
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
|
||||
private final CriteriaChain criteriaChain = new CriteriaChain();
|
||||
private final Set<CriteriaEntry> queryCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<CriteriaEntry> filterCriteriaEntries = new LinkedHashSet<>();
|
||||
private final Set<Criteria> subCriteria = new LinkedHashSet<>();
|
||||
|
||||
// region criteria creation
|
||||
// region criteria creation
|
||||
|
||||
/**
|
||||
* @return factory method to create an and-Criteria that is not bound to a field
|
||||
@@ -89,8 +89,8 @@ public class Criteria {
|
||||
}
|
||||
|
||||
public Criteria() {
|
||||
recalculateHashCode();
|
||||
}
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Criteria with provided field name
|
||||
@@ -113,7 +113,7 @@ public class Criteria {
|
||||
|
||||
this.field = field;
|
||||
this.criteriaChain.add(this);
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,7 +143,7 @@ public class Criteria {
|
||||
this.field = field;
|
||||
this.criteriaChain.addAll(criteriaChain);
|
||||
this.criteriaChain.add(this);
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,7 +197,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria not() {
|
||||
this.negating = true;
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public class Criteria {
|
||||
Assert.isTrue(boost >= 0, "boost must not be negative");
|
||||
|
||||
this.boost = boost;
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ public class Criteria {
|
||||
Assert.notNull(criteria, "Cannot chain 'null' criteria.");
|
||||
|
||||
this.criteriaChain.add(criteria);
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ public class Criteria {
|
||||
Assert.notNull(criterias, "Cannot chain 'null' criterias.");
|
||||
|
||||
this.criteriaChain.addAll(Arrays.asList(criterias));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ public class Criteria {
|
||||
orCriteria.subCriteria.addAll(criteria.subCriteria);
|
||||
orCriteria.boost = criteria.boost;
|
||||
orCriteria.negating = criteria.isNegating();
|
||||
orCriteria.recalculateHashCode();
|
||||
orCriteria.recalculateHashCode();
|
||||
return orCriteria;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ public class Criteria {
|
||||
Assert.notNull(criteria, "criteria must not be null");
|
||||
|
||||
subCriteria.add(criteria);
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria is(Object o) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EQUALS, o));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria exists() {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXISTS));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ public class Criteria {
|
||||
}
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, false, true);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.STARTS_WITH, s));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, true, true);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.CONTAINS, s));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ public class Criteria {
|
||||
|
||||
assertNoBlankInWildcardQuery(s, true, false);
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.ENDS_WITH, s));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,7 @@ public class Criteria {
|
||||
Assert.notNull(values, "Collection of 'in' values must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.IN, values));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ public class Criteria {
|
||||
Assert.notNull(values, "Collection of 'NotIn' values must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_IN, values));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria expression(String s) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXPRESSION, s));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@ public class Criteria {
|
||||
*/
|
||||
public Criteria fuzzy(String s) {
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.FUZZY, s));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ public class Criteria {
|
||||
Assert.notNull(upperBound, "upperBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ public class Criteria {
|
||||
Assert.notNull(upperBound, "upperBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS, upperBound));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -569,7 +569,7 @@ public class Criteria {
|
||||
Assert.notNull(lowerBound, "lowerBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ public class Criteria {
|
||||
Assert.notNull(lowerBound, "lowerBound must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER, lowerBound));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -601,7 +601,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES, value));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES_ALL, value));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -631,7 +631,7 @@ public class Criteria {
|
||||
public Criteria empty() {
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EMPTY));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ public class Criteria {
|
||||
public Criteria notEmpty() {
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_EMPTY));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -660,7 +660,7 @@ public class Criteria {
|
||||
Assert.notNull(value, "value must not be null");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.REGEXP, value));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ public class Criteria {
|
||||
Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -696,7 +696,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries
|
||||
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -714,7 +714,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries
|
||||
.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -731,7 +731,7 @@ public class Criteria {
|
||||
Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -749,7 +749,7 @@ public class Criteria {
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX,
|
||||
new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ public class Criteria {
|
||||
Assert.notNull(location, "Distance value for near criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -784,7 +784,7 @@ public class Criteria {
|
||||
Assert.notNull(location, "Distance value for near criteria must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ public class Criteria {
|
||||
Assert.isTrue(StringUtils.hasLength(geoLocation), "geoLocation value must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance }));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -816,7 +816,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_INTERSECTS, geoShape));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -831,7 +831,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_IS_DISJOINT, geoShape));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_WITHIN, geoShape));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ public class Criteria {
|
||||
Assert.notNull(geoShape, "geoShape must not be null");
|
||||
|
||||
filterCriteriaEntries.add(new CriteriaEntry(OperationKey.GEO_CONTAINS, geoShape));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -873,7 +873,7 @@ public class Criteria {
|
||||
Assert.notNull(query, "has_child query must not be null.");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_CHILD, query));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -887,7 +887,7 @@ public class Criteria {
|
||||
Assert.notNull(query, "has_parent query must not be null.");
|
||||
|
||||
queryCriteriaEntries.add(new CriteriaEntry(OperationKey.HAS_PARENT, query));
|
||||
recalculateHashCode();
|
||||
recalculateHashCode();
|
||||
return this;
|
||||
}
|
||||
// endregion
|
||||
@@ -909,7 +909,7 @@ public class Criteria {
|
||||
|
||||
// region equals/hashcode
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
@@ -937,19 +937,19 @@ public class Criteria {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
private void recalculateHashCode() {
|
||||
int result = field != null ? field.hashCode() : 0;
|
||||
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
||||
result = 31 * result + (negating ? 1 : 0);
|
||||
// the criteriaChain contains "this" object, so we need to filter it out
|
||||
// to avoid a stackoverflow here, because the hashcode implementation
|
||||
// uses the element's hashcodes
|
||||
result = 31 * result + criteriaChain.filter(this).hashCode();
|
||||
result = 31 * result + queryCriteriaEntries.hashCode();
|
||||
result = 31 * result + filterCriteriaEntries.hashCode();
|
||||
result = 31 * result + subCriteria.hashCode();
|
||||
this.hashCode = result;
|
||||
}
|
||||
private void recalculateHashCode() {
|
||||
int result = field != null ? field.hashCode() : 0;
|
||||
result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
||||
result = 31 * result + (negating ? 1 : 0);
|
||||
// the criteriaChain contains "this" object, so we need to filter it out
|
||||
// to avoid a stackoverflow here, because the hashcode implementation
|
||||
// uses the element's hashcodes
|
||||
result = 31 * result + criteriaChain.filter(this).hashCode();
|
||||
result = 31 * result + queryCriteriaEntries.hashCode();
|
||||
result = 31 * result + filterCriteriaEntries.hashCode();
|
||||
result = 31 * result + subCriteria.hashCode();
|
||||
this.hashCode = result;
|
||||
}
|
||||
// endregion
|
||||
|
||||
@Override
|
||||
@@ -1141,7 +1141,7 @@ public class Criteria {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
|
||||
@@ -354,7 +354,6 @@ public class DeleteQuery {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Query getQuery() {
|
||||
return query;
|
||||
}
|
||||
@@ -648,6 +647,7 @@ public class DeleteQuery {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("VariableNotUsedInsideIf")
|
||||
public DeleteQuery build() {
|
||||
if (luceneQuery == null) {
|
||||
if (defaultField != null) {
|
||||
|
||||
+9
-9
@@ -29,14 +29,14 @@ import org.springframework.util.Assert;
|
||||
public class FetchSourceFilter implements SourceFilter {
|
||||
|
||||
@Nullable private final Boolean fetchSource;
|
||||
@Nullable private final String[] includes;
|
||||
@Nullable private final String[] excludes;
|
||||
private final String @Nullable [] includes;
|
||||
private final String @Nullable [] excludes;
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public static SourceFilter of(@Nullable Boolean fetchSource, @Nullable final String[] includes,
|
||||
@Nullable final String[] excludes) {
|
||||
public static SourceFilter of(@Nullable Boolean fetchSource, final String @Nullable [] includes,
|
||||
final String @Nullable [] excludes) {
|
||||
return new FetchSourceFilter(fetchSource, includes, excludes);
|
||||
}
|
||||
|
||||
@@ -50,25 +50,25 @@ public class FetchSourceFilter implements SourceFilter {
|
||||
return builderFunction.apply(new FetchSourceFilterBuilder()).build();
|
||||
}
|
||||
|
||||
public FetchSourceFilter(@Nullable Boolean fetchSource, @Nullable final String[] includes,
|
||||
@Nullable final String[] excludes) {
|
||||
public FetchSourceFilter(@Nullable Boolean fetchSource, final String @Nullable [] includes,
|
||||
final String @Nullable [] excludes) {
|
||||
this.fetchSource = fetchSource;
|
||||
this.includes = includes;
|
||||
this.excludes = excludes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean fetchSource() {
|
||||
public @Nullable Boolean fetchSource() {
|
||||
return fetchSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String[] getIncludes() {
|
||||
public String @Nullable [] getIncludes() {
|
||||
return includes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String[] getExcludes() {
|
||||
public String @Nullable [] getExcludes() {
|
||||
return excludes;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ public class GeoDistanceOrder extends Order {
|
||||
}
|
||||
|
||||
private GeoDistanceOrder(String property, GeoPoint geoPoint, Sort.Direction direction, DistanceType distanceType,
|
||||
Mode mode, String unit, Boolean ignoreUnmapped) {
|
||||
@Nullable Mode mode, String unit, Boolean ignoreUnmapped) {
|
||||
super(direction, property, mode);
|
||||
this.geoPoint = geoPoint;
|
||||
this.distanceType = distanceType;
|
||||
@@ -59,7 +59,7 @@ public class GeoDistanceOrder extends Order {
|
||||
return distanceType;
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
public @Nullable Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class SimpleField implements Field {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof SimpleField that))
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
+16
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.query.types;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.reindex;
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class DefaultRoutingResolver implements RoutingResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRouting() {
|
||||
public @Nullable String getRouting() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+15
-2
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* classes/interfaces for specification and implementation of Elasticsearch routing.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.routing;
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/**
|
||||
* Classes and interfaces to access to script API of Elasticsearch
|
||||
* (https://www.elastic.co/guide/en/elasticsearch/reference/8.5/script-apis.html).
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.script;
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -110,7 +109,6 @@ public class SqlResponse {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Iterator<Map.Entry<Column, JsonValue>> iterator() {
|
||||
return row.entrySet().iterator();
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* Classes and interfaces to access to SQL API of Elasticsearch.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.sql;
|
||||
|
||||
+16
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.core.suggest.response;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch;
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public interface ElasticsearchRepository<T, ID> extends PagingAndSortingReposito
|
||||
* @param pageable , must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable);
|
||||
Page<T> searchSimilar(T entity, String @Nullable [] fields, Pageable pageable);
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository.aot;
|
||||
|
||||
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository.cdi;
|
||||
|
||||
+16
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository.config;
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
/**
|
||||
* infrastructure to define the Elasticsearch mapping for an index.
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository;
|
||||
|
||||
+9
-3
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repository.query;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
@@ -82,13 +84,17 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
|
||||
protected abstract boolean isExistsQuery();
|
||||
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
public Object execute(@Nullable Object[] parameters) {
|
||||
|
||||
ElasticsearchParametersParameterAccessor parameterAccessor = getParameterAccessor(parameters);
|
||||
// need this additional var, otherwise the code analysis does not recognize
|
||||
// that parameters is not null after the check
|
||||
var parametersNN = Objects.requireNonNull(parameters, "parameters must not be null");
|
||||
|
||||
ElasticsearchParametersParameterAccessor parameterAccessor = getParameterAccessor(parametersNN);
|
||||
ResultProcessor resultProcessor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor);
|
||||
Class<?> clazz = resultProcessor.getReturnedType().getDomainType();
|
||||
|
||||
Query query = createQuery(parameters);
|
||||
Query query = createQuery(parametersNN);
|
||||
|
||||
IndexCoordinates index = parameterAccessor
|
||||
.getIndexCoordinates(elasticsearchOperations.getIndexCoordinatesFor(clazz));
|
||||
|
||||
+12
-6
@@ -18,6 +18,9 @@ package org.springframework.data.elasticsearch.repository.query;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||
@@ -72,10 +75,12 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
public Object execute(@Nullable Object[] parameters) {
|
||||
|
||||
Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parameters)
|
||||
: execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parameters));
|
||||
var parametersNN = Objects.requireNonNull(parameters, "parameters must not be null");
|
||||
|
||||
Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parametersNN)
|
||||
: execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parametersNN));
|
||||
return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result;
|
||||
}
|
||||
|
||||
@@ -98,7 +103,7 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
|
||||
Class<?> domainType = returnedType.getDomainType();
|
||||
Class<?> typeToRead = returnedType.getTypeToRead();
|
||||
|
||||
if (SearchHit.class.isAssignableFrom(typeToRead)) {
|
||||
if (typeToRead != null && SearchHit.class.isAssignableFrom(typeToRead)) {
|
||||
typeToRead = queryMethod.unwrappedReturnType;
|
||||
}
|
||||
|
||||
@@ -145,9 +150,10 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
|
||||
.map(count -> count > 0);
|
||||
} else if (queryMethod.isCollectionQuery()) {
|
||||
return (query, type, targetType, indexCoordinates) -> operations.search(query.setPageable(accessor.getPageable()),
|
||||
type, targetType, indexCoordinates);
|
||||
type, Objects.requireNonNull(targetType), indexCoordinates);
|
||||
} else {
|
||||
return operations::search;
|
||||
return (query, type, targetType, index) -> operations.search(query, type, Objects.requireNonNull(targetType),
|
||||
index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository.query;
|
||||
|
||||
+16
@@ -1,2 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022-present 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.
|
||||
*/
|
||||
|
||||
@org.jspecify.annotations.NullMarked
|
||||
package org.springframework.data.elasticsearch.repository.query.parser;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user