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

Java8升Java17时Hibernate报错:CDI BeanManager未就绪

解决Hibernate 6.5 + OpenLiberty 24中CDI BeanManager未就绪的初始化问题

问题背景

升级BAS应用至Java 17,同步将Hibernate从5.3.29.Final升级到6.5.0.Final,运行在OpenLiberty 24.0.0.4上,server.xml已启用cdi-4.0、jakartaee-10.0特性。启动时抛出错误:

[ERROR ] CWWJP0015E: org.hibernate.jpa.HibernatePersistenceProvider创建mpce持久化单元的容器EntityManager工厂时出错,具体为Error attempting to apply AttributeConverter: org.hibernate.resource.beans.container.internal.NotYetReadyException: CDI BeanManager not (yet) ready to use。

已尝试以下方案但未解决:

  • 在persistence.xml中添加<property name="hibernate.delay_cdi_access" value="true"/>延迟Hibernate访问CDI
  • 创建BeanManagerProvider类提供BeanManager实例,在persistence.xml中配置<property name="hibernate.cdi.beanmanager" value="com.example.BeanManagerProvider.getBeanManager"/>
  • 确认Jakarta EE、CDI与Hibernate ORM 6.5.0.Final的兼容性(当前cdi v4、OpenLiberty 24.0.0.4、Jakarta EE10均兼容)

核心需求:让Hibernate在CDI BeanManager完全就绪后再执行初始化。

可行解决方案

1. 调整OpenLiberty的JPA初始化顺序

OpenLiberty中可通过配置确保JPA特性在CDI之后启动,修改server.xml:

<featureManager>
    <feature>cdi-4.0</feature>
    <feature>jakartaee-10.0</feature>
    <!-- 明确JPA在CDI之后加载 -->
    <feature>jpa-3.1</feature>
</featureManager>

<!-- 配置持久化单元为JTA类型,依赖容器事务管理 -->
<persistenceUnit id="mpce" transactionType="JTA">
    <jta-data-source>jdbc/yourDataSource</jta-data-source>
    <class>com.example.YourEntity</class>
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</persistenceUnit>

同时在persistence.xml中设置transaction-type="JTA",避免Hibernate提前触发初始化。

2. 强制Hibernate使用CDI扩展优先逻辑

在persistence.xml中添加以下属性,让Hibernate依赖CDI扩展处理BeanManager的延迟获取:

<property name="hibernate.cdi.extension.preferred" value="true"/>

该配置会让Hibernate放弃早期直接访问BeanManager的逻辑,转而通过CDI扩展的生命周期回调获取实例。

3. 排除Hibernate自带CDI扩展依赖(解决冲突)

检查项目依赖,若存在Hibernate自带的hibernate-cdi模块,可能与OpenLiberty内置CDI容器冲突,在Maven pom.xml中排除:

<dependency>
    <groupId>org.hibernate.orm</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.5.0.Final</version>
    <exclusions>
        <exclusion>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-cdi</artifactId>
        </exclusion>
    </exclusions>
</dependency>

4. 自定义CDI扩展触发Hibernate初始化

创建CDI扩展类,在CDI容器完全初始化后再创建EntityManagerFactory:

package com.example;

import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.spi.AfterDeploymentValidation;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class HibernateInitializerExtension {
    public void onDeploymentComplete(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
        // CDI就绪后初始化持久化单元
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("mpce");
        // 将EMF作为事件发布,供应用内其他组件使用
        beanManager.fireEvent(emf);
    }
}

在META-INF/services/jakarta.enterprise.inject.spi.Extension文件中注册该扩展:

com.example.HibernateInitializerExtension

同时修改persistence.xml,移除自动初始化配置,由扩展类触发创建。

验证步骤

  1. 重启OpenLiberty,检查日志是否不再出现NotYetReadyException
  2. 验证自定义AttributeConverter是否能被Hibernate正常加载
  3. 测试基础JPA操作(实体查询、持久化)是否正常执行

内容的提问来源于stack exchange,提问作者Anmol Ahuja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:19:56