Quarkus Hibernate Search编程式映射下SearchSession注入失败问题
在Quarkus 3.6.3中使用Hibernate Search编程式映射时,出现SearchSession无法注入的问题。此前使用注解式映射一切正常,因需要访问Panache id字段而切换为编程式映射。若不在任意实体上添加@Indexed注解,就会抛出如下异常:
java.lang.RuntimeException: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: jakarta.enterprise.inject.spi.DeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.hibernate.search.mapper.orm.session.SearchSession and qualifiers [@Default] - java member: app.api.search.SearchDao#searchSession - declared on CLASS bean [types=[app.api.search.SearchDao, java.lang.Object], qualifiers=[@Default, @Any], target=app.api.search.SearchDao] at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:1453) at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:311) at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:160) at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:472) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:849) at io.quarkus.builder.BuildContext.run(BuildContext.java:256) at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) at java.base/java.lang.Thread.run(Thread.java:833) at org.jboss.threads.JBossThread.run(JBossThread.java:501) Caused by: jakarta.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.hibernate.search.mapper.orm.session.SearchSession and qualifiers [@Default] - java member: app.api.search.SearchDao#searchSession - declared on CLASS bean [types=[app.api.search.SearchDao, java.lang.Object], qualifiers=[@Default, @Any], target=app.api.search.SearchDao] at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:478) at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:624) at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:299) ... 13 more
切换为编程式映射的代码如下:
@SearchExtension public class SearchConfigurer implements ElasticsearchAnalysisConfigurer, HibernateOrmSearchMappingConfigurer { @Override public void configure(HibernateOrmMappingConfigurationContext context) { // 我们使用编程式映射而非注解式映射,因为需要访问Panache id字段 // 现在所有配置都集中在一处 TypeMappingStep product = context.programmaticMapping() .type(Product.class); product.indexed(); product.property("id").documentId(); [...] } @Override public void configure(ElasticsearchAnalysisConfigurationContext context) { context.tokenFilter("dutch_stop") .type("stop") .param("stopwords", "_dutch_"); context.tokenFilter("dutch_stemmer") .type("stemmer") .param("language", "dutch"); context.tokenFilter("dutch_synonyms") .type("synonym") .param("synonyms", synonyms()); context.tokenFilter("dutch_decompounder") .type("dictionary_decompounder") .param("word_list", words()); context.analyzer("w_dutch").custom() .tokenizer("standard") .tokenFilters("lowercase", "dutch_stemmer", "dutch_decompounder", "dutch_synonyms"); } }
目前的临时解决方法是在某个无需搜索的实体上添加@Indexed注解,但这并非合理方案。也曾尝试给配置器Bean添加@Named注解,并在application.properties中配置quarkus.hibernate-search-orm.mapping.configurer=bean:myMappingConfigurer,但问题仍未解决。使用的依赖包括quarkus-hibernate-search-orm-elasticsearch、quarkus-hibernate-orm-rest-data-panache及quarkus-hibernate-orm-panache等。
这个问题的核心是Quarkus的Hibernate Search扩展会根据是否存在@Indexed注解自动判断是否启用搜索功能:当完全使用编程式映射时,没有实体标注@Indexed,扩展会认为不需要初始化搜索相关组件,因此不会注册SearchSession的CDI Bean,导致注入失败。
可以通过以下两种方式解决:
- 强制启用Hibernate Search
在application.properties中添加配置,强制Quarkus初始化Hibernate Search相关组件,无视是否存在@Indexed注解:
quarkus.hibernate-search-orm.enabled=true
该配置会直接告诉扩展必须启用搜索功能,确保SearchSession等必要CDI Bean被正常注册。
- 确保编程式映射配置被正确识别
若选择此路径,需确认两点:- 配置器类所在的包在Quarkus的CDI扫描范围内,若不在默认扫描包下,需通过
quarkus.index-dependency系列配置指定扫描依赖; quarkus.hibernate-search-orm.mapping.configurer的配置值与@Named注解的名称完全匹配,比如配置器标注@Named("myMappingConfigurer"),则配置项需为quarkus.hibernate-search-orm.mapping.configurer=bean:myMappingConfigurer。
- 配置器类所在的包在Quarkus的CDI扫描范围内,若不在默认扫描包下,需通过
通常第一种方法是最直接有效的,它绕过了扩展的自动检测逻辑,确保搜索组件始终被初始化。
内容的提问来源于stack exchange,提问作者Arjan Lamers

