You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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被正常注册。

  • 确保编程式映射配置被正确识别
    若选择此路径,需确认两点:
    1. 配置器类所在的包在Quarkus的CDI扫描范围内,若不在默认扫描包下,需通过quarkus.index-dependency系列配置指定扫描依赖;
    2. quarkus.hibernate-search-orm.mapping.configurer的配置值与@Named注解的名称完全匹配,比如配置器标注@Named("myMappingConfigurer"),则配置项需为quarkus.hibernate-search-orm.mapping.configurer=bean:myMappingConfigurer。

通常第一种方法是最直接有效的,它绕过了扩展的自动检测逻辑,确保搜索组件始终被初始化。

内容的提问来源于stack exchange,提问作者Arjan Lamers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:47:34