GlassFish7+JakartaEE10集成Hibernate遇NoClassDefFoundError求助
问题:GlassFish 7 + Hibernate 6.2.6 JTA数据源配置报错NoClassDefFoundError
我正在尝试让Hibernate与GlassFish 7的JDBC连接池配合工作,连接池已正确配置且ping测试通过,已将mysql-connector-j-8.0.33.jar和hibernate-core-6.2.6.Final.jar放入glassfish/domain/domain1/lib目录。
使用RESOURCE_LOCAL类型的持久化单元时一切正常,但切换到JTA数据源的持久化单元时出现以下错误:
java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/ReflectionManager
以下是我的相关配置和代码:
persistence.xml 配置
<?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="persistence-unit"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <jta-data-source>jpa1</jta-data-source> <class>jpa1.User</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> <!-- <persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <properties> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:8889/learn_it_jpa?autoReconnect=true&useSSL=false"/> <property name="jakarta.persistence.jdbc.user" value="root"/> <property name="jakarta.persistence.jdbc.password" value="root"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="jakarta.persistence.schema-generation.database.action" value="none"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> </properties> </persistence-unit> --> </persistence>
pom.xml 配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>jpa1</artifactId> <packaging>war</packaging> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <version>1.0-SNAPSHOT</version> <name>jpa1 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>10.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.2.6.Final</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>jpa1</finalName> </build> </project>
JTA使用代码
package jpa1; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet(name = "homeServlet", value = "/start") public class HomeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("persistence-unit"); EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); User user1 = new User("Max","Mustermann", User.Gender.MALE, 10, 50000, 1000); entityManager.persist(user1); entityManager.getTransaction().commit(); List<User> results = entityManager .createQuery("Select a from User a", User.class) .getResultList(); entityManager.close(); entityManagerFactory.close(); req.setAttribute("test", results); req.getRequestDispatcher("start.jsp").forward(req, resp); } }
实体类代码
package jpa1; import jakarta.persistence.*; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "gender") @Enumerated(EnumType.ORDINAL) private Gender gender; @Column(name = "age") private int age; @Column(name = "salary") private int salary; @Column(name = "test") private int test; public User() { } public enum Gender { MALE, FEMALE } public User(String firstName, String lastName, Gender gender, int age, int salary, int test) { this.firstName = firstName; this.lastName = lastName; this.gender = gender; this.age = age; this.salary = salary; this.test = test; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public Gender getGender() { return gender; } public String getGenderStr() { switch (gender) { case MALE -> { return "Männlich"; } case FEMALE -> { return "Weiblich"; } default -> { return ""; } } } public int getAge() { return age; } }
解决方案
这个错误是因为缺少Hibernate依赖包hibernate-commons-annotations,Hibernate 6.x版本中该包是hibernate-core的间接依赖,手动放置jar包时容易遗漏。
解决步骤:
- 下载与Hibernate 6.2.6.Final匹配的
hibernate-commons-annotations-6.0.6.Final.jar - 将该jar包放入
glassfish/domain/domain1/lib目录 - 重启GlassFish服务器
额外优化建议:
- 移除persistence.xml中重复的DDL配置项,
jakarta.persistence.schema-generation.database.action和hibernate.hbm2ddl.auto保留一个即可,推荐保留hibernate.hbm2ddl.auto="update" - MySQL 8.x环境下,替换方言为
org.hibernate.dialect.MySQL8Dialect,兼容性更好 - JTA模式下,可改用容器管理的实体管理器(通过
@PersistenceContext注入),更符合Jakarta EE规范
内容的提问来源于stack exchange,提问作者Hendrik
相关产品推荐
相关产品推荐

