TomEE 9加载Hibernate 6.2持久化单元失败:NoSuchFieldError: UUID
问题分析与解决方案
核心错误根源
java.lang.NoSuchFieldError: UUID 本质是依赖冲突:TomEE 9.0.0自带OpenJPA作为默认JPA实现,与你引入的Hibernate 6.2.2类库存在类路径冲突,导致JPA相关API类(如UUID相关定义)加载混乱;同时配置文件的命名空间、事务类型与TomEE的Jakarta EE 9环境不匹配,引发持久化单元找不到、生命周期转换错误。
分步解决步骤
1. 强制隔离容器自带JPA依赖
TomEE默认优先加载容器级类库,需让WEB-INF/lib中的Hibernate优先加载:
- 在项目
WEB-INF目录下新建tomee.xml,添加类加载配置:<TomEE> <Context> <Loader delegate="false"/> <!-- 优先加载WEB-INF/lib内的类 --> </Context> </TomEE> - Maven依赖中排除TomEE自带的JPA API,仅保留Hibernate核心与PostgreSQL驱动:
<dependencies> <!-- Hibernate核心,打包进WAR --> <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>6.2.2.Final</version> </dependency> <!-- PostgreSQL驱动 --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> </dependency> <!-- Jakarta EE API由TomEE提供,无需打包 --> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies>
2. 修正persistence.xml配置
确保配置使用Jakarta EE 9命名空间,并明确指定Hibernate作为提供商:
- 配置文件路径:
src/main/resources/META-INF/persistence.xml(Maven项目),最终需在WAR的WEB-INF/classes/META-INF下 - 示例配置(RESOURCE_LOCAL模式,无需TomEE数据源):
注意:所有属性前缀为<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="MyPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <!-- 手动添加实体类,或开启自动扫描 --> <class>com.yourpackage.YourEntity</class> <properties> <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/your_db"/> <property name="jakarta.persistence.jdbc.user" value="postgres"/> <property name="jakarta.persistence.jdbc.password" value="your_password"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>jakarta.persistence.*,而非旧版的javax.persistence.*
3. 修正持久化单元调用代码
确保使用Jakarta EE的API类,而非旧Java EE类:
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; public class EntityManagerHelper { private static final EntityManagerFactory EMF = Persistence.createEntityManagerFactory("MyPU"); public static EntityManager getEntityManager() { return EMF.createEntityManager(); } public static void closeFactory() { EMF.close(); } }
4. 清理冗余依赖
执行mvn dependency:tree查看依赖树,排除所有与OpenJPA、旧版JPA相关的传递依赖,确保仅保留Hibernate与PostgreSQL驱动。
内容的提问来源于stack exchange,提问作者DDD
相关产品推荐
相关产品推荐

