diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml index 8ffe2b9b60fdf..2882f24031683 100644 --- a/bom/runtime/pom.xml +++ b/bom/runtime/pom.xml @@ -84,12 +84,12 @@ 1.3.4 5.4.12.Final 6.1.2.Final - 6.0.0.Beta4 + 6.0.0.Beta5 5.10.0.Final 1.1.1.Final 1.7 7.6.0.Final - 7.5.0 + 7.6.0 1.3.8 2.2.18 1.0.6.Final diff --git a/build-parent/pom.xml b/build-parent/pom.xml index 94a36db3b031f..506c6f03c6509 100644 --- a/build-parent/pom.xml +++ b/build-parent/pom.xml @@ -17,7 +17,7 @@ 6.15 - 7.5.0 + 7.6.0 4.1.1 diff --git a/docs/src/main/asciidoc/hibernate-search-elasticsearch.adoc b/docs/src/main/asciidoc/hibernate-search-elasticsearch.adoc index 8b8a085e55eb9..3aee9ceb91d33 100644 --- a/docs/src/main/asciidoc/hibernate-search-elasticsearch.adoc +++ b/docs/src/main/asciidoc/hibernate-search-elasticsearch.adoc @@ -483,7 +483,7 @@ In our existing `LibraryResource`, we just need to inject the following methods @QueryParam Optional size) { return Search.session(em) // <5> .search(Author.class) // <6> - .predicate(f -> + .where(f -> pattern == null || pattern.trim().isEmpty() ? f.matchAll() : // <7> f.simpleQueryString() @@ -510,8 +510,11 @@ the mass indexer should then only be used when you change your indexing configur [NOTE] ==== -Hibernate Search supports a significant part of the Elasticsearch predicates (match, range, nested, phrase, spatial...). -Feel free to explore the DSL by using autocompletion. +The Hibernate Search DSL supports a significant subset of the Elasticsearch predicates (match, range, nested, phrase, spatial...). +Feel free to explore the DSL using autocompletion. + +When that's not enough, you can always fall back to +[defining a predicate using JSON directly](https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#search-dsl-predicate-extensions-elasticsearch-from-json). ==== == Configuring the application @@ -536,7 +539,7 @@ quarkus.hibernate-search.elasticsearch.version=7 <5> quarkus.hibernate-search.elasticsearch.analysis.configurer=org.acme.hibernate.search.elasticsearch.config.AnalysisConfigurer <6> quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy=drop-and-create <7> quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status=yellow <8> -quarkus.hibernate-search.automatic-indexing.synchronization.strategy=searchable <9> +quarkus.hibernate-search.automatic-indexing.synchronization.strategy=sync <9> ---- <1> We won't use SSL so we disable it to have a more compact native executable. <2> Let's create a PostgreSQL datasource. @@ -551,7 +554,8 @@ Since the mapping is created at build time to reduce startup time, Hibernate Sea This is for testing purposes with the Elasticsearch Docker container. It should not be used in production. <9> This means that we wait for the entities to be searchable before considering a write complete. -While, on a production setup, the `committed` default might be a suitable value, using `searchable` is especially important when testing as you need the entities to be searchable immediately. +On a production setup, the `write-sync` default will provide better performance. +Using `sync` is especially important when testing as you need the entities to be searchable immediately. [TIP] For more information about the Hibernate Search extension configuration please refer to the <>. diff --git a/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchClasses.java b/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchClasses.java index dac09fea84658..68bd5e16a47f2 100644 --- a/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchClasses.java +++ b/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchClasses.java @@ -3,28 +3,28 @@ import java.util.Arrays; import java.util.List; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.AbstractCompositeAnalysisDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.AnalysisDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.AnalysisDefinitionJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.AnalyzerDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.AnalyzerDefinitionJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.CharFilterDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.NormalizerDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.NormalizerDefinitionJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.TokenFilterDefinition; -import org.hibernate.search.backend.elasticsearch.analysis.model.esnative.impl.TokenizerDefinition; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.AbstractTypeMapping; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.AbstractTypeMappingJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.DynamicType; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.ElasticsearchFormatJsonAdapter; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.ElasticsearchRoutingTypeJsonAdapter; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.PropertyMapping; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.PropertyMappingJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.RootTypeMapping; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.RootTypeMappingJsonAdapterFactory; -import org.hibernate.search.backend.elasticsearch.document.model.esnative.impl.RoutingType; -import org.hibernate.search.backend.elasticsearch.index.settings.esnative.impl.Analysis; -import org.hibernate.search.backend.elasticsearch.index.settings.esnative.impl.IndexSettings; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.aliases.impl.IndexAliasDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.aliases.impl.IndexAliasDefinitionJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.AnalysisDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.AnalysisDefinitionJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.AnalyzerDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.AnalyzerDefinitionJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.CharFilterDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.NormalizerDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.NormalizerDefinitionJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.TokenFilterDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.analysis.impl.TokenizerDefinition; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.AbstractTypeMapping; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.DynamicType; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.FormatJsonAdapter; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMapping; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.PropertyMappingJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RootTypeMapping; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RootTypeMappingJsonAdapterFactory; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RoutingType; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.mapping.impl.RoutingTypeJsonAdapter; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.Analysis; +import org.hibernate.search.backend.elasticsearch.lowlevel.index.settings.impl.IndexSettings; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; import org.hibernate.search.mapper.pojo.mapping.definition.annotation.processing.TypeMapping; import org.jboss.jandex.DotName; @@ -37,27 +37,27 @@ class HibernateSearchClasses { org.hibernate.search.mapper.pojo.mapping.definition.annotation.processing.PropertyMapping.class.getName()); static final DotName TYPE_MAPPING_META_ANNOTATION = DotName.createSimple(TypeMapping.class.getName()); - static final List SCHEMA_MAPPING_CLASSES = Arrays.asList( - DotName.createSimple(AbstractTypeMapping.class.getName()), - DotName.createSimple(AbstractTypeMappingJsonAdapterFactory.class.getName()), - DotName.createSimple(DynamicType.class.getName()), - DotName.createSimple(ElasticsearchFormatJsonAdapter.class.getName()), - DotName.createSimple(ElasticsearchRoutingTypeJsonAdapter.class.getName()), - DotName.createSimple(PropertyMapping.class.getName()), - DotName.createSimple(PropertyMappingJsonAdapterFactory.class.getName()), - DotName.createSimple(RootTypeMapping.class.getName()), - DotName.createSimple(RootTypeMappingJsonAdapterFactory.class.getName()), - DotName.createSimple(RoutingType.class.getName()), - DotName.createSimple(IndexSettings.class.getName()), - DotName.createSimple(Analysis.class.getName()), - DotName.createSimple(AnalysisDefinition.class.getName()), - DotName.createSimple(AbstractCompositeAnalysisDefinition.class.getName()), - DotName.createSimple(AnalyzerDefinition.class.getName()), - DotName.createSimple(AnalyzerDefinitionJsonAdapterFactory.class.getName()), - DotName.createSimple(NormalizerDefinition.class.getName()), - DotName.createSimple(NormalizerDefinitionJsonAdapterFactory.class.getName()), - DotName.createSimple(TokenizerDefinition.class.getName()), - DotName.createSimple(TokenFilterDefinition.class.getName()), - DotName.createSimple(CharFilterDefinition.class.getName()), - DotName.createSimple(AnalysisDefinitionJsonAdapterFactory.class.getName())); + static final List> GSON_CLASSES = Arrays.asList( + AbstractTypeMapping.class, + DynamicType.class, + FormatJsonAdapter.class, + RoutingTypeJsonAdapter.class, + PropertyMapping.class, + PropertyMappingJsonAdapterFactory.class, + RootTypeMapping.class, + RootTypeMappingJsonAdapterFactory.class, + RoutingType.class, + IndexSettings.class, + Analysis.class, + AnalysisDefinition.class, + AnalyzerDefinition.class, + AnalyzerDefinitionJsonAdapterFactory.class, + NormalizerDefinition.class, + NormalizerDefinitionJsonAdapterFactory.class, + TokenizerDefinition.class, + TokenFilterDefinition.class, + CharFilterDefinition.class, + AnalysisDefinitionJsonAdapterFactory.class, + IndexAliasDefinition.class, + IndexAliasDefinitionJsonAdapterFactory.class); } diff --git a/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchElasticsearchProcessor.java b/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchElasticsearchProcessor.java index 87a4ff2c972f5..268a481ca1a24 100644 --- a/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchElasticsearchProcessor.java +++ b/extensions/hibernate-search-elasticsearch/deployment/src/main/java/io/quarkus/hibernate/search/elasticsearch/HibernateSearchElasticsearchProcessor.java @@ -1,8 +1,8 @@ package io.quarkus.hibernate.search.elasticsearch; +import static io.quarkus.hibernate.search.elasticsearch.HibernateSearchClasses.GSON_CLASSES; import static io.quarkus.hibernate.search.elasticsearch.HibernateSearchClasses.INDEXED; import static io.quarkus.hibernate.search.elasticsearch.HibernateSearchClasses.PROPERTY_MAPPING_META_ANNOTATION; -import static io.quarkus.hibernate.search.elasticsearch.HibernateSearchClasses.SCHEMA_MAPPING_CLASSES; import static io.quarkus.hibernate.search.elasticsearch.HibernateSearchClasses.TYPE_MAPPING_META_ANNOTATION; import java.util.ArrayList; @@ -10,8 +10,6 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; -import java.util.function.Function; -import java.util.stream.Stream; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; @@ -177,9 +175,15 @@ private void registerReflection(IndexView index, BuildProducer c.toString()).toArray(String[]::new); + for (Class gsonClass : GSON_CLASSES) { + Class currentClass = gsonClass; + while (currentClass != Object.class) { + reflectiveClassCollector.add(DotName.createSimple(currentClass.getName())); + currentClass = currentClass.getSuperclass(); + } + } + + String[] reflectiveClasses = reflectiveClassCollector.stream().map(DotName::toString).toArray(String[]::new); reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, reflectiveClasses)); for (Type reflectiveHierarchyType : reflectiveHierarchyCollector) { @@ -204,6 +208,7 @@ private static void addReflectiveClass(IndexView index, Set reflectiveC Type superClassType = classInfo.superClassType(); while (superClassType != null && !superClassType.name().toString().equals("java.lang.Object")) { + reflectiveClassCollector.add(superClassType.name()); if (superClassType instanceof ClassType) { superClassType = index.getClassByName(superClassType.name()).superClassType(); } else if (superClassType instanceof ParameterizedType) { diff --git a/extensions/hibernate-search-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/elasticsearch/runtime/HibernateSearchElasticsearchRuntimeConfig.java b/extensions/hibernate-search-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/elasticsearch/runtime/HibernateSearchElasticsearchRuntimeConfig.java index 89e067def4547..36f625b6d9233 100644 --- a/extensions/hibernate-search-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/elasticsearch/runtime/HibernateSearchElasticsearchRuntimeConfig.java +++ b/extensions/hibernate-search-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/elasticsearch/runtime/HibernateSearchElasticsearchRuntimeConfig.java @@ -8,7 +8,7 @@ import org.hibernate.search.backend.elasticsearch.index.IndexLifecycleStrategyName; import org.hibernate.search.backend.elasticsearch.index.IndexStatus; -import org.hibernate.search.mapper.orm.automaticindexing.AutomaticIndexingSynchronizationStrategyName; +import org.hibernate.search.mapper.orm.automaticindexing.session.AutomaticIndexingSynchronizationStrategyNames; import org.hibernate.search.mapper.orm.search.loading.EntityLoadingCacheLookupStrategy; import org.hibernate.search.util.common.SearchException; import org.hibernate.search.util.common.impl.StringHelper; @@ -210,13 +210,167 @@ public static class AutomaticIndexingSynchronizationConfig { /** * The synchronization strategy to use when indexing automatically. *

- * Defines the status for which you wait before considering the operation completed by Hibernate Search. + * Defines how complete indexing should be before resuming the application thread + * after a database transaction is committed. *

- * Use {@code queued} or {@code committed} in production environments. - * {@code searchable} is useful in integration tests. + * Available values: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
+ *

+ * Strategy + *

+ *
+ *

+ * Guarantees when the application thread resumes + *

+ *
+ *

+ * Throughput + *

+ *
+ *

+ * Changes applied + *

+ *
+ *

+ * Changes safe from crash/power loss + *

+ *
+ *

+ * Changes visible on search + *

+ *
+ *

+ * {@value AutomaticIndexingSynchronizationStrategyNames#ASYNC} + *

+ *
+ *

+ * No guarantee + *

+ *
+ *

+ * No guarantee + *

+ *
+ *

+ * No guarantee + *

+ *
+ *

+ * Best + *

+ *
+ *

+ * {@value AutomaticIndexingSynchronizationStrategyNames#WRITE_SYNC} (default) + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * No guarantee + *

+ *
+ *

+ * Medium + *

+ *
+ *

+ * {@value AutomaticIndexingSynchronizationStrategyNames#READ_SYNC} + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * No guarantee + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * Medium to worst + *

+ *
+ *

+ * {@value AutomaticIndexingSynchronizationStrategyNames#SYNC} + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * Guaranteed + *

+ *
+ *

+ * Worst + *

+ *
+ *

+ * See + * this + * section of the reference documentation + * for more information. */ - @ConfigItem(defaultValue = "committed") - AutomaticIndexingSynchronizationStrategyName strategy; + @ConfigItem(defaultValue = AutomaticIndexingSynchronizationStrategyNames.WRITE_SYNC) + String strategy; } @ConfigGroup diff --git a/integration-tests/hibernate-search-elasticsearch/src/main/java/io/quarkus/it/hibernate/search/elasticsearch/search/HibernateSearchTestResource.java b/integration-tests/hibernate-search-elasticsearch/src/main/java/io/quarkus/it/hibernate/search/elasticsearch/search/HibernateSearchTestResource.java index 084b7bf4bae77..5be594a5ce1a9 100644 --- a/integration-tests/hibernate-search-elasticsearch/src/main/java/io/quarkus/it/hibernate/search/elasticsearch/search/HibernateSearchTestResource.java +++ b/integration-tests/hibernate-search-elasticsearch/src/main/java/io/quarkus/it/hibernate/search/elasticsearch/search/HibernateSearchTestResource.java @@ -39,7 +39,7 @@ public String testSearch() { SearchSession searchSession = Search.session(entityManager); List person = searchSession.search(Person.class) - .predicate(f -> f.match().field("name").matching("john")) + .where(f -> f.match().field("name").matching("john")) .sort(f -> f.field("name_sort")) .fetchHits(20); @@ -48,7 +48,7 @@ public String testSearch() { assertEquals("John Irving", person.get(1).getName()); person = searchSession.search(Person.class) - .predicate(f -> f.nested().objectField("address").nest( + .where(f -> f.nested().objectField("address").nest( f.match().field("address.city").matching("london"))) .sort(f -> f.field("name_sort")) .fetchHits(20); @@ -71,12 +71,12 @@ public String testPurge() { } @PUT - @Path("/flush") + @Path("/refresh") @Produces(MediaType.TEXT_PLAIN) - public String testFlush() { + public String testRefresh() { SearchSession searchSession = Search.session(entityManager); - searchSession.workspace().flush(); + searchSession.workspace().refresh(); return "OK"; } @@ -88,7 +88,7 @@ public String testSearchEmpty() { SearchSession searchSession = Search.session(entityManager); List person = searchSession.search(Person.class) - .predicate(f -> f.matchAll()) + .where(f -> f.matchAll()) .fetchHits(20); assertEquals(0, person.size()); diff --git a/integration-tests/hibernate-search-elasticsearch/src/main/resources/application.properties b/integration-tests/hibernate-search-elasticsearch/src/main/resources/application.properties index 485b87928daf2..dc7d8d90a4413 100644 --- a/integration-tests/hibernate-search-elasticsearch/src/main/resources/application.properties +++ b/integration-tests/hibernate-search-elasticsearch/src/main/resources/application.properties @@ -11,4 +11,5 @@ quarkus.hibernate-orm.database.generation=drop-and-create quarkus.hibernate-search.elasticsearch.version=7 quarkus.hibernate-search.elasticsearch.analysis.configurer=io.quarkus.it.hibernate.search.elasticsearch.search.DefaultITAnalysisConfigurer quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy=drop-and-create-and-drop -quarkus.hibernate-search.automatic-indexing.synchronization.strategy=searchable +quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status=yellow +quarkus.hibernate-search.automatic-indexing.synchronization.strategy=sync diff --git a/integration-tests/hibernate-search-elasticsearch/src/test/java/io/quarkus/it/hibernate/search/elasticsearch/HibernateSearchTest.java b/integration-tests/hibernate-search-elasticsearch/src/test/java/io/quarkus/it/hibernate/search/elasticsearch/HibernateSearchTest.java index 503ca7805ddb6..7ac08d451a80e 100644 --- a/integration-tests/hibernate-search-elasticsearch/src/test/java/io/quarkus/it/hibernate/search/elasticsearch/HibernateSearchTest.java +++ b/integration-tests/hibernate-search-elasticsearch/src/test/java/io/quarkus/it/hibernate/search/elasticsearch/HibernateSearchTest.java @@ -23,7 +23,7 @@ public void testSearch() throws Exception { .statusCode(200) .body(is("OK")); - RestAssured.when().put("/test/hibernate-search/flush").then() + RestAssured.when().put("/test/hibernate-search/refresh").then() .statusCode(200) .body(is("OK"));