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

如何在Hibernate BeforeExecutionGenerator中注入Bean(Quarkus环境)

在Quarkus中为Hibernate BeforeExecutionGenerator注入Bean或配置属性

问题原因

Hibernate的BeforeExecutionGenerator实例由Hibernate自身负责实例化,并不受CDI容器管理,因此直接使用@Inject注解或标记@ApplicationScoped都无法触发CDI的注入逻辑。

解决方案

1. 手动获取CDI Bean实例

在Quarkus中,可以通过Arc.container()手动获取CDI管理的Bean实例,这是Quarkus原生推荐的方式:

修改MyIdGenerator类如下:

import io.quarkus.arc.Arc;
import io.quarkus.arc.Instance;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.BeforeExecutionGenerator;
import org.hibernate.id.enhanced.EventType;
import java.util.EnumSet;

public class MyIdGenerator implements BeforeExecutionGenerator {

    @Override
    public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue,
                           EventType eventType) {
        // 获取OtherService的CDI实例
        Instance<OtherService> serviceInstance = Arc.container().instance(OtherService.class);
        OtherService service = serviceInstance.get();
        return service.nextId();
    }

    @Override
    public EnumSet<EventType> getEventTypes() {
        return INSERT_ONLY;
    }
}

2. 注入配置属性

如果需要读取配置属性,可以使用Quarkus的ConfigProvider直接获取:

import io.quarkus.arc.Arc;
import io.quarkus.arc.Instance;
import io.smallrye.config.ConfigProvider;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.BeforeExecutionGenerator;
import org.hibernate.id.enhanced.EventType;
import java.util.EnumSet;

public class MyIdGenerator implements BeforeExecutionGenerator {

    private final String customConfig;

    public MyIdGenerator() {
        // 从配置文件读取属性,比如application.properties中的my.id.generator.prefix
        this.customConfig = ConfigProvider.getConfig().getValue("my.id.generator.prefix", String.class);
    }

    @Override
    public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue,
                           EventType eventType) {
        Instance<OtherService> serviceInstance = Arc.container().instance(OtherService.class);
        OtherService service = serviceInstance.get();
        // 结合配置属性生成ID
        return service.nextIdWithPrefix(customConfig);
    }

    @Override
    public EnumSet<EventType> getEventTypes() {
        return INSERT_ONLY;
    }
}

注意事项

  • 不要在生成器的构造方法中获取CDI Bean,因为此时CDI容器可能尚未完全初始化,应在generate方法中执行获取操作。
  • 确保被获取的Bean(如OtherService)已被CDI正确管理(比如标记了@ApplicationScoped、@Singleton等作用域注解)。

内容的提问来源于stack exchange,提问作者Andrei Yusupau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:50:13