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

模块化环境下Hibernate运行失败问题排查与求助

模块化项目中迁移Jakarta Hibernate的JBoss Logging访问问题解决

问题背景

正将基于javax JPA的旧工具迁移至Jakarta版本的新版Hibernate,在模块化项目中运行时遇到问题:实例化HibernatePersistenceProvider类时触发ExceptionInInitializerError,根源为JBoss Logging的模块访问问题。

已搭建MCVE复现问题:使用Gradle 8.10.2与Java 23,配置相关依赖与module-info.java后,运行测试出现两类核心错误:

  • 使用JBoss Logging 3.6.1.Final时,提示无法访问org.hibernate.internal.EntityManagerMessageLogger
  • 降级至3.5.0.Final时,出现IllegalAccessError,提示org.jboss.logging模块未读取java.logging模块
  • 降级Hibernate至6.6.1.Final也无法解决问题

移除module-info.java并注释gradle.build的doFirst块后问题消失,但无法放弃模块化,现求助以下问题:

  1. 是否需修改module-info.java?
  2. 是否需调整依赖版本?
  3. 是否需添加--add-opens参数?
  4. 是否不应直接实例化HibernatePersistenceProvider?
  5. 这是否是Hibernate的Bug?

简言之,哪里操作有误?该如何修复?


问题解答

1. 是否需修改module-info.java?

是,必须调整模块声明,确保你的模块正确依赖并开放必要权限:

module your.module.name {
    // 声明依赖核心模块
    requires jakarta.persistence;
    requires org.hibernate.core;
    requires org.jboss.logging;
    
    // 开放你的持久化相关包,允许Hibernate和JBoss Logging反射访问
    opens your.persistence.package to org.hibernate.core, org.jboss.logging;
}

注意:org.hibernate.internal是Hibernate内部包,模块系统默认不对外暴露,不能直接依赖,需通过opens指令让框架能反射访问你的代码。

2. 是否需调整依赖版本?

是,必须保证Hibernate与JBoss Logging版本完全兼容:

  • 不要手动指定JBoss Logging版本,使用Hibernate官方BOM统一管理依赖版本,避免版本冲突:
dependencies {
    implementation platform('org.hibernate.orm:hibernate-platform:6.7.2.Final')
    implementation 'org.hibernate.orm:hibernate-core'
    implementation 'jakarta.persistence:jakarta.persistence-api'
}

Hibernate的BOM会自动引入适配当前版本的JBoss Logging,无需手动指定。

3. 是否需添加--add-opens参数?

可能需要,针对JDK内部包的访问限制:
JBoss Logging需要访问部分JDK内部类,需添加以下JVM启动参数:

--add-opens java.base/java.lang=org.jboss.logging
--add-opens java.base/java.util=org.jboss.logging
--add-opens java.logging/java.util.logging=org.jboss.logging

你的模块内部类的访问需求可通过module-info.java的opens指令解决,无需额外参数。

4. 是否不应直接实例化HibernatePersistenceProvider?

是,推荐使用Jakarta JPA标准API初始化,避免直接依赖Hibernate实现类:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("your-persistence-unit");

直接实例化HibernatePersistenceProvider会绕过JPA的模块化兼容层,容易触发访问权限问题,这也是Hibernate官方推荐的标准用法。

5. 是否是Hibernate的Bug?

大概率不是,主要是模块化配置不当导致的。但如果严格按照兼容版本和配置操作后仍有问题,可能是Hibernate 6.x对Java 23(非LTS版本)的适配不足,可尝试降级到Java 21(LTS版本)验证。


完整修复步骤

  1. 修正module-info.java:添加必要的requires和opens指令,确保模块依赖与权限配置正确。
  2. 使用Hibernate BOM管理版本:移除手动指定的JBoss Logging版本,通过BOM统一控制依赖版本。
  3. 切换到JPA标准API:替换直接实例化HibernatePersistenceProvider的代码,改用Persistence.createEntityManagerFactory。
  4. 添加JVM启动参数:配置--add-opens参数,允许JBoss Logging访问JDK内部包。
  5. (可选)降级Java版本:若Java 23下问题仍存在,切换到Java 21 LTS版本测试。

内容的提问来源于stack exchange,提问作者Victor Stafusa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:22:47