RHEL6.7出现Hibernate MappingException但RHEL6.5正常的问题求助
先梳理下你的场景:
你配置了两个需要Hibernate扫描的映射包,配置代码如下:
<property name="mappingLocations"> <list> <value>classpath:com/a/b/c/**/*.hbm.xml</value> <value>classpath:com/a/b/d/**/*.hbm.xml</value> </list> </property>
该配置在RHEL 6.5上运行正常,但切换到RHEL 6.7后抛出了映射异常,报错信息如下:
Invocation of init method failed; nested exception is org.hibernate.MappingException: An association from the table abc_table refers to an unmapped class: com.a.b.d.bean.Variable.
已知abc_table的映射文件在com.a.b.c包下,com.a.b.d.bean.Variable对应的映射文件也确实存在。
可能的原因
RHEL 6.7和6.5的核心差异主要集中在默认JDK版本、系统库版本,如果你使用了应用服务器(比如JBoss、Tomcat),其版本或配置也可能有变化,这些都会间接影响Hibernate的映射加载逻辑:
- 类加载顺序问题:Hibernate按配置顺序加载映射,先处理
com.a.b.c包的文件时,com.a.b.d的映射还未被加载,导致abc_table关联的Variable类被判定为未映射。 - 类路径通配符解析差异:不同环境下(比如不同应用服务器或类加载器)对
classpath:开头的通配符解析逻辑有区别,可能导致com.a.b.d下的hbm.xml文件没被扫描到。 - JDK/依赖兼容问题:RHEL 6.7默认JDK可能从OpenJDK 6升级到7,旧版本的Hibernate在新JDK环境下可能存在类加载的兼容性问题。
解决方案
1. 调整映射加载顺序
把com.a.b.d包的映射配置放在前面,确保Variable的映射先被加载,这样后续加载abc_table的映射时就能找到对应的类:
<property name="mappingLocations"> <list> <value>classpath:com/a/b/d/**/*.hbm.xml</value> <value>classpath:com/a/b/c/**/*.hbm.xml</value> </list> </property>
2. 修改类路径通配符为classpath*:
尝试将classpath:替换为classpath*:,后者会扫描所有类路径下的匹配资源(包括多个JAR包中的),避免因类路径隔离导致的资源遗漏:
<property name="mappingLocations"> <list> <value>classpath*:com/a/b/c/**/*.hbm.xml</value> <value>classpath*:com/a/b/d/**/*.hbm.xml</value> </list> </property>
3. 验证打包后的资源完整性
在RHEL 6.7上用命令检查你的应用包(WAR/JAR)中是否包含com/a/b/d下的hbm.xml文件:
jar tvf your-application.jar | grep hbm.xml
如果发现d包的映射文件缺失,检查你的打包工具(Maven/Gradle)配置,确保这些资源被正确包含(比如Maven中要在build/resources节点配置包含xml文件)。
4. 检查JDK和Hibernate版本兼容性
用java -version查看RHEL 6.7的默认JDK版本,如果是JDK 7,而你使用的是Hibernate 3.x及以下版本,建议升级到Hibernate 4.x或更高版本,或者调整JDK版本为和RHEL 6.5一致的版本。
5. 排查应用服务器类加载问题
如果你使用了应用服务器,检查以下配置:
- 确保Hibernate的所有依赖JAR都放在应用自身的
WEB-INF/lib(WAR包)或lib目录(JAR包),而不是服务器的全局lib目录,避免容器类加载器和应用类加载器的隔离导致类找不到。 - 检查服务器的类加载顺序配置(比如JBoss的
jboss-deployment-structure.xml),确保应用的类优先加载。
内容的提问来源于stack exchange,提问作者VijayD

