1
0
mirror of synced 2026-08-31 21:24:28 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Peter-Josef Meisch cd1bd52466 Fix formatting of DateFormat.strict_date_optional_time_nanos.
Original Pull Request: #3337
Closes: #3334

Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com>
2026-08-30 18:14:45 +02:00
Peter-Josef Meisch cc7bd2b729 Upgrade to Elasticsearch 9.5.2.
Original Pull Request: #3336
Closes: #3333

Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com>
2026-08-29 13:45:39 +02:00
Peter-Josef Meisch 4d0ec05411 Fix script handling when building an UpdateQuery.
Original Pull Request #3331
Closes #3324

Signed-off-by: Peter-Josef Meisch <pj.meisch@sothawo.com>
2026-08-22 17:09:28 +02:00
Mark Paluch 2b402c7424 Prepare next development iteration.
See #3296
2026-08-21 11:01:30 +02:00
8 changed files with 64 additions and 43 deletions
+19 -7
View File
@@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId> <artifactId>spring-data-elasticsearch</artifactId>
<version>6.2.0-M1</version> <version>6.2.0-SNAPSHOT</version>
<parent> <parent>
<groupId>org.springframework.data.build</groupId> <groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId> <artifactId>spring-data-parent</artifactId>
<version>4.2.0-M1</version> <version>4.2.0-SNAPSHOT</version>
</parent> </parent>
<name>Spring Data Elasticsearch</name> <name>Spring Data Elasticsearch</name>
@@ -18,11 +18,11 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url> <url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties> <properties>
<springdata.commons>4.2.0-M1</springdata.commons> <springdata.commons>4.2.0-SNAPSHOT</springdata.commons>
<!-- version of the ElasticsearchClient --> <!-- version of the ElasticsearchClient -->
<elasticsearch-java>9.5.0</elasticsearch-java> <elasticsearch-java>9.5.2</elasticsearch-java>
<elasticsearch-rest-client>9.5.0</elasticsearch-rest-client> <elasticsearch-rest-client>9.5.2</elasticsearch-rest-client>
<hoverfly>0.20.2</hoverfly> <hoverfly>0.20.2</hoverfly>
<log4j>2.25.4</log4j> <log4j>2.25.4</log4j>
@@ -508,8 +508,20 @@
</profiles> </profiles>
<repositories> <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> </repositories>
</project> </project>
@@ -4,10 +4,12 @@
[[new-features.6-2-0]] [[new-features.6-2-0]]
== New in Spring Data Elasticsearch 6.2 == New in Spring Data Elasticsearch 6.2
* Upgrade to Elasticsearch 9.5.0 * Upgrade to Elasticsearch 9.5.2
* Allow to provide non-standard (custom) index options for `@Field` / `@InnerField` * Allow to provide non-standard (custom) index options for `@Field` / `@InnerField`
* Support Elasticsearch Serverless * Support Elasticsearch Serverless
* Support propert resolution in index name expressions (https://github.com/spring-projects/spring-data-elasticsearch/issues/3310[GH #3310]) * Support propert resolution in index name expressions (https://github.com/spring-projects/spring-data-elasticsearch/issues/3310[GH #3310])
* Fix script handling when building an UpdateQuery (https://github.com/spring-projects/spring-data-elasticsearch/issues/3324[GH #3324])
* Fix formatting of DateFormat.strict_date_optional_time_nanos (https://github.com/spring-projects/spring-data-elasticsearch/issues/3334[GH #3334])
[[new-features.6-1-0]] [[new-features.6-1-0]]
== New in Spring Data Elasticsearch 6.1 == New in Spring Data Elasticsearch 6.1
@@ -6,7 +6,7 @@ The following table shows the Elasticsearch and Spring versions that are used by
[cols="^,^,^,^",options="header"] [cols="^,^,^,^",options="header"]
|=== |===
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
| 2026.1 | 6.2.x | 9.5.0 | 7.0.x | 2026.1 | 6.2.x | 9.5.2 | 7.0.x
| 2026.0 | 6.1.x | 9.4.2 | 7.0.x | 2026.0 | 6.1.x | 9.4.2 | 7.0.x
| 2025.1 | 6.0.x | 9.2.2 | 7.0.x | 2025.1 | 6.0.x | 9.2.2 | 7.0.x
| 2025.0 | 5.5.xfootnote:oom[Out of maintenance] | 8.18.1 | 6.2.x | 2025.0 | 5.5.xfootnote:oom[Out of maintenance] | 8.18.1 | 6.2.x
@@ -88,7 +88,7 @@ public enum DateFormat {
* @since 5.3 * @since 5.3
*/ */
strict_date_optional_time("uuuu-MM-dd['T'HH:mm:ss.SSSXXX]"), // strict_date_optional_time("uuuu-MM-dd['T'HH:mm:ss.SSSXXX]"), //
strict_date_optional_time_nanos("uuuu-MM-dd['T'HH:mm:ss.SSSSSSXXX]"), // strict_date_optional_time_nanos("uuuu-MM-dd['T'HH:mm:ss.SSSSSSSSSXXX]"), //
date_time("uuuu-MM-dd'T'HH:mm:ss.SSSXXX"), // date_time("uuuu-MM-dd'T'HH:mm:ss.SSSXXX"), //
/** /**
* @since 5.3 * @since 5.3
@@ -70,11 +70,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.Optional;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -234,7 +234,8 @@ class RequestConverter extends AbstractQueryProcessor {
for (Alias alias : indexSettings.getAliases()) { for (Alias alias : indexSettings.getAliases()) {
co.elastic.clients.elasticsearch.indices.Alias esAlias = co.elastic.clients.elasticsearch.indices.Alias co.elastic.clients.elasticsearch.indices.Alias esAlias = co.elastic.clients.elasticsearch.indices.Alias
.of(ab -> { .of(ab -> {
co.elastic.clients.elasticsearch.indices.Alias.Builder aliasBuilder = ab.filter(getQuery(alias.getFilter(), null)) co.elastic.clients.elasticsearch.indices.Alias.Builder aliasBuilder = ab
.filter(getQuery(alias.getFilter(), null))
.isHidden(alias.getHidden()) .isHidden(alias.getHidden())
.isWriteIndex(alias.getWriteIndex()); .isWriteIndex(alias.getWriteIndex());
getRouting(alias.getRouting()).ifPresent(aliasBuilder::routing); getRouting(alias.getRouting()).ifPresent(aliasBuilder::routing);
@@ -807,7 +808,7 @@ class RequestConverter extends AbstractQueryProcessor {
Assert.notNull(indexCoordinates, "indexCoordinates must not be null"); Assert.notNull(indexCoordinates, "indexCoordinates must not be null");
return GetRequest.of(grb -> { return GetRequest.of(grb -> {
GetRequest.Builder builder = grb // GetRequest.Builder builder = grb //
.index(indexCoordinates.getIndexName()) // .index(indexCoordinates.getIndexName()) //
.id(id); // .id(id); //
getRouting(routing).ifPresent(builder::routing); getRouting(routing).ifPresent(builder::routing);
@@ -846,7 +847,7 @@ class RequestConverter extends AbstractQueryProcessor {
List<MultiGetOperation> multiGetOperations = query.getIdsWithRouting().stream() List<MultiGetOperation> multiGetOperations = query.getIdsWithRouting().stream()
.map(idWithRouting -> MultiGetOperation.of(mgo -> { .map(idWithRouting -> MultiGetOperation.of(mgo -> {
MultiGetOperation.Builder builder = mgo // MultiGetOperation.Builder builder = mgo //
.index(index.getIndexName()) // .index(index.getIndexName()) //
.id(idWithRouting.id()) // .id(idWithRouting.id()) //
.source(sourceConfig); .source(sourceConfig);
@@ -1071,29 +1072,7 @@ class RequestConverter extends AbstractQueryProcessor {
return UpdateRequest.of(uqb -> { return UpdateRequest.of(uqb -> {
uqb.index(indexName).id(query.getId()); uqb.index(indexName).id(query.getId());
var scriptData = query.getScriptData(); uqb.script(getScript(query.getScriptData()));
var script = scriptData != null ? scriptData.script() : null;
if (script != null) {
Map<String, JsonData> params = new HashMap<>();
if (query.getParams() != null) {
query.getParams().forEach((key, value) -> params.put(key, JsonData.of(value, jsonpMapper)));
}
uqb.script(sb -> {
sb
.lang(scriptData.language())
.params(params);
if (script != null) {
sb.source(s -> s.scriptString(script));
}
sb.id(scriptData.scriptName());
return sb;
});
}
uqb uqb
.doc(query.getDocument()) .doc(query.getDocument())
@@ -1980,6 +1959,7 @@ class RequestConverter extends AbstractQueryProcessor {
} }
return Optional.empty(); return Optional.empty();
} }
Optional<String> getRouting(@Nullable String routing1, @Nullable String routing2) { Optional<String> getRouting(@Nullable String routing1, @Nullable String routing2) {
return getRouting(routing1).or(() -> getRouting(routing2)); return getRouting(routing1).or(() -> getRouting(routing2));
} }
@@ -16,6 +16,10 @@
package org.springframework.data.elasticsearch.client.elc; package org.springframework.data.elasticsearch.client.elc;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.fail;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -131,10 +135,28 @@ class RequestConverterTest {
.documentUpdateRequest(updateQuery, IndexCoordinates.of("foo"), null, null); .documentUpdateRequest(updateQuery, IndexCoordinates.of("foo"), null, null);
assertThat(updateRequest.id()).isEqualTo("queryId"); assertThat(updateRequest.id()).isEqualTo("queryId");
assertThat(updateRequest.script()).isNotNull();
assertThat(updateRequest.script().source().scriptString()).isEqualTo("script"); assertThat(updateRequest.script().source().scriptString()).isEqualTo("script");
assertThat(updateRequest.script().id()).isEqualTo("scriptName"); assertThat(updateRequest.script().id()).isEqualTo("scriptName");
} }
@Test // #3324
@DisplayName("should allow update script with only an id and no script code")
void shouldAllowUpdateScriptWithOnlyAnIdAndNoScriptCode() {
var updateQuery = UpdateQuery
.builder("queryId")
.withScriptName("scriptName")
.build();
UpdateRequest<org.springframework.data.elasticsearch.core.document.Document, ?> updateRequest = requestConverter
.documentUpdateRequest(updateQuery, IndexCoordinates.of("foo"), null, null);
assertThat(updateRequest.id()).isEqualTo("queryId");
assertThat(updateRequest.script()).isNotNull();
assertThat(updateRequest.script().source()).isNull();
assertThat(updateRequest.script().id()).isEqualTo("scriptName");
}
@Test @Test
void getRouting() { void getRouting() {
@@ -148,5 +170,4 @@ class RequestConverterTest {
assertEquals("5", requestConverter.getRouting(null, "5").get()); assertEquals("5", requestConverter.getRouting(null, "5").get());
} }
} }
@@ -27,7 +27,8 @@ import org.springframework.data.elasticsearch.annotations.DateFormat;
*/ */
class ElasticsearchDateConverterUnitTests { class ElasticsearchDateConverterUnitTests {
private final ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Berlin")); public static final ZoneId zoneEuropeBerlin = ZoneId.of("Europe/Berlin");
private final ZonedDateTime zdt = ZonedDateTime.now(zoneEuropeBerlin);
@ParameterizedTest // DATAES-716 @ParameterizedTest // DATAES-716
@EnumSource(DateFormat.class) @EnumSource(DateFormat.class)
@@ -274,10 +275,14 @@ class ElasticsearchDateConverterUnitTests {
check(ElasticsearchDateConverter.of(DateFormat.date_optional_time), LocalDateTime.class); check(ElasticsearchDateConverter.of(DateFormat.date_optional_time), LocalDateTime.class);
} }
@Test // #2676 @Test // #2676, #3334
@DisplayName("should convert strict_date_optional_time_nanos") @DisplayName("should convert strict_date_optional_time_nanos")
void shouldConvertStrictDateOptionalTime() { void shouldConvertStrictDateOptionalTime() {
check(ElasticsearchDateConverter.of(DateFormat.strict_date_optional_time_nanos), LocalDateTime.class); LocalDateTime parsed = check(ElasticsearchDateConverter.of(DateFormat.strict_date_optional_time_nanos),
LocalDateTime.class);
// additional check that all nanoseconds are re-read
var zoned = ZonedDateTime.of(parsed, zoneEuropeBerlin);
assertThat(zoned).isEqualTo(zdt);
} }
@Test // #1647 @Test // #1647
@@ -418,11 +423,12 @@ class ElasticsearchDateConverterUnitTests {
check(ElasticsearchDateConverter.of("basic_date_time ||invalid-pattern"), LocalDateTime.class); check(ElasticsearchDateConverter.of("basic_date_time ||invalid-pattern"), LocalDateTime.class);
} }
private <T extends TemporalAccessor> void check(ElasticsearchDateConverter converter, Class<T> type) { private <T extends TemporalAccessor> T check(ElasticsearchDateConverter converter, Class<T> type) {
String formatted = converter.format(zdt); String formatted = converter.format(zdt);
T parsed = converter.parse(formatted, type); T parsed = converter.parse(formatted, type);
assertThat(parsed).isNotNull(); assertThat(parsed).isNotNull();
return parsed;
} }
} }
@@ -15,7 +15,7 @@
# #
# #
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
sde.testcontainers.image-version=9.5.0 sde.testcontainers.image-version=9.5.2
# #
# #
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13 # needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13