From 3cc5694fdd4ab5aaab7ed52a9bc1c81f54288d2b Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 3 Feb 2026 23:56:09 +0100 Subject: [PATCH 1/5] HSEARCH-5564 Add compatibility with Elasticsearch 9.3 --- .../dialect/impl/ElasticsearchDialectFactory.java | 2 +- .../dialect/impl/ElasticsearchDialectFactoryTest.java | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactory.java b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactory.java index f2c56a0b8af..ace80c5a5a6 100644 --- a/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactory.java +++ b/backend/elasticsearch/src/main/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactory.java @@ -213,7 +213,7 @@ else if ( minor == 0 ) { } private ElasticsearchProtocolDialect createProtocolDialectElasticV9(ElasticsearchVersion version, int minor) { - if ( minor > 2 ) { + if ( minor > 3 ) { VersionLog.INSTANCE.unknownElasticsearchVersion( version ); } return new Elasticsearch81ProtocolDialect(); diff --git a/backend/elasticsearch/src/test/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactoryTest.java b/backend/elasticsearch/src/test/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactoryTest.java index ae481f1493f..2c0b64bd273 100644 --- a/backend/elasticsearch/src/test/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactoryTest.java +++ b/backend/elasticsearch/src/test/java/org/hibernate/search/backend/elasticsearch/dialect/impl/ElasticsearchDialectFactoryTest.java @@ -341,10 +341,18 @@ public static List params() { ElasticsearchDistributionName.ELASTIC, "9.2.0", "9.2.0", Elasticsearch814ModelDialect.class, Elasticsearch81ProtocolDialect.class ), - successWithWarning( + success( + ElasticsearchDistributionName.ELASTIC, "9.3", "9.3.0", + Elasticsearch814ModelDialect.class, Elasticsearch81ProtocolDialect.class + ), + success( ElasticsearchDistributionName.ELASTIC, "9.3.0", "9.3.0", Elasticsearch814ModelDialect.class, Elasticsearch81ProtocolDialect.class ), + successWithWarning( + ElasticsearchDistributionName.ELASTIC, "9.4.0", "9.4.0", + Elasticsearch814ModelDialect.class, Elasticsearch81ProtocolDialect.class + ), success( ElasticsearchDistributionName.OPENSEARCH, "1", "1.3.1", OpenSearch1ModelDialect.class, Elasticsearch70ProtocolDialect.class From 4f0ceb324313abe621c1db3512b2669016a3c780 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Tue, 3 Feb 2026 23:59:15 +0100 Subject: [PATCH 2/5] HSEARCH-5564 Test against Elasticsearch 9.3.0 by default --- Jenkinsfile | 5 +++-- build/container/search-backend/elastic.Dockerfile | 2 +- build/parents/build/pom.xml | 2 +- ci/dependency-update/Jenkinsfile | 4 ++-- pom.xml | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8a0a9e7322d..451ec420a1c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -256,8 +256,9 @@ stage('Configure') { new LocalElasticsearchBuildEnvironment(version: '8.18.7', condition: TestCondition.ON_DEMAND), new LocalElasticsearchBuildEnvironment(version: '8.19.6', condition: TestCondition.AFTER_MERGE), new LocalElasticsearchBuildEnvironment(version: '9.0.7', condition: TestCondition.ON_DEMAND), - new LocalElasticsearchBuildEnvironment(version: '9.1.5', condition: TestCondition.ON_DEMAND), - new LocalElasticsearchBuildEnvironment(version: '9.2.4', condition: TestCondition.BEFORE_MERGE, isDefault: true), + new LocalElasticsearchBuildEnvironment(version: '9.1.5', condition: TestCondition.ON_DEMAND), + new LocalElasticsearchBuildEnvironment(version: '9.2.4', condition: TestCondition.ON_DEMAND), + new LocalElasticsearchBuildEnvironment(version: '9.3.0', condition: TestCondition.BEFORE_MERGE, isDefault: true), // IMPORTANT: Make sure to update the documentation for any newly supported Elasticsearch versions // See version.org.elasticsearch.compatible.expected.text // and version.org.elasticsearch.compatible.regularly-tested.text in POMs. diff --git a/build/container/search-backend/elastic.Dockerfile b/build/container/search-backend/elastic.Dockerfile index 39c7d8a4a76..466195cb7ba 100644 --- a/build/container/search-backend/elastic.Dockerfile +++ b/build/container/search-backend/elastic.Dockerfile @@ -5,4 +5,4 @@ # * update `version.org.elasticsearch.latest` property in a POM file. # * update the tags for 'elasticsearch-current' and 'elasticsearch-next' builds in ci/dependency-update/Jenkinsfile # -FROM docker.io/elastic/elasticsearch:9.2.4 +FROM docker.io/elastic/elasticsearch:9.3.0 diff --git a/build/parents/build/pom.xml b/build/parents/build/pom.xml index f3713d8136d..7a475251ba7 100644 --- a/build/parents/build/pom.xml +++ b/build/parents/build/pom.xml @@ -65,7 +65,7 @@ - 7.10, 7.17, 8.18 or 9.2 + 7.10, 7.17, 8.18 or 9.3 diff --git a/ci/dependency-update/Jenkinsfile b/ci/dependency-update/Jenkinsfile index a2b3fc37092..8da3660bb2d 100644 --- a/ci/dependency-update/Jenkinsfile +++ b/ci/dependency-update/Jenkinsfile @@ -53,7 +53,7 @@ Map settings() { updateProperties: [], onlyRunTestDependingOn: ['hibernate-search-backend-elasticsearch'], // We want to use the snapshot version of an image from the ES registry since that's where they are publishing their snapshots. - additionalMavenArgs: '-Dtest.lucene.skip=true -Dtest.elasticsearch.run.elastic.image.name=docker.elastic.co/elasticsearch/elasticsearch -Dtest.elasticsearch.run.elastic.image.tag=9.2.5-SNAPSHOT', + additionalMavenArgs: '-Dtest.lucene.skip=true -Dtest.elasticsearch.run.elastic.image.name=docker.elastic.co/elasticsearch/elasticsearch -Dtest.elasticsearch.run.elastic.image.tag=9.3.1-SNAPSHOT', // This job won't change the versions in the pom. We are passing the latest Elasticsearch version through an additional maven argument `-D` skipSourceModifiedCheck: true ] @@ -65,7 +65,7 @@ Map settings() { updateProperties: [], onlyRunTestDependingOn: ['hibernate-search-backend-elasticsearch'], // We want to use the snapshot version of an image from the ES registry since that's where they are publishing their snapshots. - additionalMavenArgs: '-Dtest.lucene.skip=true -Dtest.elasticsearch.run.elastic.image.name=docker.elastic.co/elasticsearch/elasticsearch -Dtest.elasticsearch.run.elastic.image.tag=9.3.0-SNAPSHOT', + additionalMavenArgs: '-Dtest.lucene.skip=true -Dtest.elasticsearch.run.elastic.image.name=docker.elastic.co/elasticsearch/elasticsearch -Dtest.elasticsearch.run.elastic.image.tag=9.4.0-SNAPSHOT', // This job won't change the versions in the pom. We are passing the latest Elasticsearch version through an additional maven argument `-D` skipSourceModifiedCheck: true ] diff --git a/pom.xml b/pom.xml index 8965910d728..b6a15693416 100644 --- a/pom.xml +++ b/pom.xml @@ -392,7 +392,7 @@ - 9.2.4 + 9.3.0 elastic From 32f6ba199279e3d6b6553ee8dc41cb51cce86d56 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 4 Feb 2026 00:00:56 +0100 Subject: [PATCH 3/5] HSEARCH-5565 Update Elasticsearch client (elasticsearch-rest-client) to 9.3.0 # Conflicts: # bom/platform-common/pom.xml --- bom/platform-common/pom.xml | 2 +- build/parents/build/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/platform-common/pom.xml b/bom/platform-common/pom.xml index 4b85425a59b..7cb5a989f86 100644 --- a/bom/platform-common/pom.xml +++ b/bom/platform-common/pom.xml @@ -19,7 +19,7 @@ 7.3.0.CR2 - 9.2.4 + 9.3.0 9.2.4 3.4.0 2.41.2 diff --git a/build/parents/build/pom.xml b/build/parents/build/pom.xml index 7a475251ba7..5e57bf75ee1 100644 --- a/build/parents/build/pom.xml +++ b/build/parents/build/pom.xml @@ -49,7 +49,7 @@ - 9.2.4 + 9.3.0 9.2.4 3.4.0 From 5e89b019a7145dcb9630ba1c70c7044c64ca18a3 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 4 Feb 2026 00:01:36 +0100 Subject: [PATCH 4/5] HSEARCH-5566 Update Elasticsearch client (elasticsearch-rest5-client) to 9.3.0 --- bom/platform-common/pom.xml | 2 +- build/parents/build/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bom/platform-common/pom.xml b/bom/platform-common/pom.xml index 7cb5a989f86..5f90116b4a7 100644 --- a/bom/platform-common/pom.xml +++ b/bom/platform-common/pom.xml @@ -20,7 +20,7 @@ 7.3.0.CR2 9.3.0 - 9.2.4 + 9.3.0 3.4.0 2.41.2 3.3.2 diff --git a/build/parents/build/pom.xml b/build/parents/build/pom.xml index 5e57bf75ee1..8860b70f1ef 100644 --- a/build/parents/build/pom.xml +++ b/build/parents/build/pom.xml @@ -50,7 +50,7 @@ 9.3.0 - 9.2.4 + 9.3.0 3.4.0 5.5.1 From b013dac8e550259a9237e96b4f1162518afd1577 Mon Sep 17 00:00:00 2001 From: marko-bekhta Date: Wed, 4 Feb 2026 22:51:44 +0100 Subject: [PATCH 5/5] HSEARCH-5566 Skip some of the tests that Elasticsearch 9.3.0 cannot handle --- .../util/ElasticsearchTckBackendFeatures.java | 12 ++++++++++++ .../predicate/AbstractPredicateInObjectFieldIT.java | 12 ++++++++++++ .../tck/search/predicate/KnnPredicateBaseIT.java | 6 ++++++ .../tck/testsupport/util/TckBackendFeatures.java | 4 ++++ 4 files changed, 34 insertions(+) diff --git a/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/testsupport/util/ElasticsearchTckBackendFeatures.java b/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/testsupport/util/ElasticsearchTckBackendFeatures.java index 1df4a5a4fb7..50b9b31e586 100644 --- a/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/testsupport/util/ElasticsearchTckBackendFeatures.java +++ b/integrationtest/backend/elasticsearch/src/test/java/org/hibernate/search/integrationtest/backend/elasticsearch/testsupport/util/ElasticsearchTckBackendFeatures.java @@ -568,4 +568,16 @@ public T aggregatedSumNullValue(Class clazz) { } return super.aggregatedSumNullValue( clazz ); } + + @Override + public boolean canHandleDeepNestedPredicate(FieldTypeDescriptor fieldTypeDescriptor) { + if ( ByteVectorFieldTypeDescriptor.INSTANCE.equals( fieldTypeDescriptor ) ) { + return isActualVersion( + es -> !es.isMatching( "9.3.0" ), + os -> true, + aoss -> true + ); + } + return super.canHandleDeepNestedPredicate( fieldTypeDescriptor ); + } } diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractPredicateInObjectFieldIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractPredicateInObjectFieldIT.java index 8f91696d6c0..38db05ffb5b 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractPredicateInObjectFieldIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/AbstractPredicateInObjectFieldIT.java @@ -5,6 +5,7 @@ package org.hibernate.search.integrationtest.backend.tck.search.predicate; import static org.hibernate.search.util.impl.integrationtest.common.assertion.SearchResultAssert.assertThatQuery; +import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.util.Collection; @@ -82,6 +83,7 @@ void nestedX1_implicit(SimpleMappedIndex mainIndex, void nestedX2_explicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> f.nested( mainIndex.binding().nested.absolutePath ) .add( f.nested( mainIndex.binding().nested.nested.absolutePath ) @@ -95,6 +97,7 @@ void nestedX2_explicit(SimpleMappedIndex mainIndex, void nestedX2_implicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> predicate( f, mainIndex.binding().nested.nested, 0, dataSet ) ) .routing( dataSet.routingKey ) ) @@ -106,6 +109,7 @@ void nestedX2_implicit(SimpleMappedIndex mainIndex, void nestedX2_explicit_implicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> f.nested( mainIndex.binding().nested.absolutePath ) .add( predicate( f, mainIndex.binding().nested.nested, 0, dataSet ) ) ) @@ -118,6 +122,7 @@ void nestedX2_explicit_implicit(SimpleMappedIndex mainIndex, void nestedX3_explicitX2_implicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> f.nested( mainIndex.binding().nested.absolutePath ) .add( f.nested( mainIndex.binding().nested.nested.absolutePath ) @@ -131,6 +136,7 @@ void nestedX3_explicitX2_implicit(SimpleMappedIndex mainIndex, void nestedX3_explicit_implicitX2(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> f.nested( mainIndex.binding().nested.absolutePath ) .add( predicate( f, mainIndex.binding().nested.nested.nested, 0, dataSet ) ) ) @@ -143,6 +149,7 @@ void nestedX3_explicit_implicitX2(SimpleMappedIndex mainIndex, void nestedFlattenedNested_implicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); assertThatQuery( mainIndex.query() .where( f -> predicate( f, mainIndex.binding().nested.flattened.nested, 0, dataSet ) ) .routing( dataSet.routingKey ) ) @@ -159,6 +166,7 @@ void nestedFlattenedNested_implicit(SimpleMappedIndex mainIndex, void multiIndex_missingNestedField_implicit(SimpleMappedIndex mainIndex, SimpleMappedIndex missingFieldIndex, AbstractPredicateDataSet dataSet) { + assumeTrue( canHandleDeepNestedPredicate( dataSet ) ); StubMappingScope scope = mainIndex.createScope( missingFieldIndex ); // The "nested" predicate should not match anything in missingFieldIndex @@ -183,6 +191,10 @@ void multiIndex_missingNestedField_implicit(SimpleMappedIndex main protected abstract PredicateFinalStep predicate(SearchPredicateFactory f, ObjectFieldBinding objectFieldBinding, int matchingDocOrdinal, AbstractPredicateDataSet dataSet); + protected boolean canHandleDeepNestedPredicate(AbstractPredicateDataSet dataSet) { + return true; + } + abstract static class AbstractObjectBinding { final String absolutePath; final SimpleFieldModelsByType field; diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/KnnPredicateBaseIT.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/KnnPredicateBaseIT.java index 15b13fd5399..a1272b57ef2 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/KnnPredicateBaseIT.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/search/predicate/KnnPredicateBaseIT.java @@ -168,6 +168,12 @@ protected PredicateFinalStep predicate(SearchPredicateFactory f, String fieldPat return knnPredicateOptionsStep( f, fieldPath, matchingDocOrdinal, dataSet.values.matchingArg( matchingDocOrdinal ) ); } + + @Override + protected boolean canHandleDeepNestedPredicate(AbstractPredicateDataSet dataSet) { + return TckConfiguration.get().getBackendFeatures() + .canHandleDeepNestedPredicate( ( (DataSet) dataSet ).fieldType ); + } } @Nested diff --git a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TckBackendFeatures.java b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TckBackendFeatures.java index e2ecf632885..8b697874ddd 100644 --- a/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TckBackendFeatures.java +++ b/integrationtest/backend/tck/src/main/java/org/hibernate/search/integrationtest/backend/tck/testsupport/util/TckBackendFeatures.java @@ -230,4 +230,8 @@ public R accumulatedNullValue(ProjectionCollector.Provider collecto public T aggregatedSumNullValue(Class clazz) { return null; } + + public boolean canHandleDeepNestedPredicate(FieldTypeDescriptor fieldTypeDescriptor) { + return true; + } }