如何解决EntityManager 'student_pu_test'的PersistenceException异常
调用Persistence.createEntityManagerFactory()时抛出javax.persistence.PersistenceException,提示找不到名为student_pu_test的EntityManager对应的持久化提供者。已核查persistence.xml配置、依赖项及初始化逻辑,但问题仍未解决。
相关代码与配置
StudentRepository类
package fr.charly.jPATutorial; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class StudentRepository { private EntityManager entityManager; private EntityManagerFactory emf; public StudentRepository() { this.emf = Persistence.createEntityManagerFactory("student_pu_test"); this.entityManager = this.emf.createEntityManager(); } public StudentRepository(String pu) { this.emf = Persistence.createEntityManagerFactory(pu); this.entityManager = this.emf.createEntityManager(); } public Student add(Student student) { entityManager.getTransaction().begin(); entityManager.persist(student); entityManager.getTransaction().commit(); return student; } public Student find(Long id) { return entityManager.find(Student.class, id); } public Student update(Student student) { Student studentToUpdate = find(student.getId()); entityManager.getTransaction().begin(); studentToUpdate.setFirstName(student.getFirstName()); studentToUpdate.setLastName(student.getLastName()); entityManager.getTransaction().commit(); return studentToUpdate; } public void delete(Student student) { entityManager.getTransaction().begin(); entityManager.remove(student); entityManager.getTransaction().commit(); } public void close() { this.entityManager.close(); this.emf.close(); } }
StudentRepositoryTest类
package fr.charly.jPATutorial; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; public class StudentRepositoryTest { private static StudentRepository repository; @BeforeAll public static void beforeClass() throws Exception { repository = new StudentRepository("student_pu_test"); } @AfterAll public static void afterClass() throws Exception { if (repository != null) { repository.close(); } } @BeforeEach public void setUp() throws Exception { } @AfterEach public void tearDown() throws Exception { } @Test public void add() { Student student = new Student(); student.setLastName("Red"); student.setFirstName("Alan"); repository.add(student); assertNotNull(student.getId()); assertTrue(student.getId() != null); } @Test public void find() { Student student = new Student(); student.setLastName("Red"); student.setFirstName("Alan"); repository.add(student); student = repository.find(student.getId()); assertNotNull(student); assertNotNull(student.getId()); assertEquals("Red", student.getLastName()); } @Test public void update() { Student student = new Student(); student.setLastName("Red"); student.setFirstName("Alan"); student = repository.add(student); student.setLastName("Green"); student = repository.update(student); assertNotNull(student); assertEquals("Green", student.getLastName()); assertEquals("Alan", student.getFirstName()); } @Test public void delete() { Student student = new Student(); student.setLastName("Red"); student.setFirstName("Alan"); student = repository.add(student); repository.delete(student); student = repository.find(student.getId()); assertNull(student); } }
persistence.xml配置
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="student_pu_test" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <class>fr.charly.jPATutorial.Student</class> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" /> <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> <property name="javax.persistence.jdbc.user" value="sa" /> <property name="javax.persistence.jdbc.password" value="" /> <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="create" /> </properties> </persistence-unit> </persistence>
错误信息
juin 05, 2024 9:18:01 AM javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver log AVERTISSEMENT: javax.persistence.spi::No valid providers found. [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.111 s <<< FAILURE! -- in fr.charly.jPATutorial.StudentRepositoryTest [ERROR] fr.charly.jPATutorial.StudentRepositoryTest -- Time elapsed: 0.111 s <<< ERROR! javax.persistence.PersistenceException: No Persistence provider for EntityManager named student_pu_test at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:85) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54) at fr.charly.jPATutorial.StudentRepository.<init>(StudentRepository.java:18) at fr.charly.jPATutorial.StudentRepositoryTest.beforeClass(StudentRepositoryTest.java:20) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) [INFO] [INFO] Results: [INFO] [ERROR] Errors: [ERROR] StudentRepositoryTest.beforeClass:20 » Persistence No Persistence provider for EntityManager named student_pu_test [INFO] [ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [ERROR] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.116 s [INFO] Finished at: 2024-06-05T09:18:01+02:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.2.2:test (default-test) on project jPATutorial: [ERROR] [ERROR] Please refer to C:\Users\Charly\Desktop\developpement\workspace\jPATutorial\target\surefire-reports for the individual test results. [ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump, and [date].dumpstream.
排查思路与解决方案
验证Hibernate依赖完整性
确保项目依赖中包含Hibernate核心库及JPA API,Maven依赖示例:<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.15.Final</version> <!-- 版本需与JPA 2.0兼容 --> </dependency> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version> <scope>test</scope> </dependency>可通过
mvn dependency:tree命令检查依赖树,确认hibernate-core已被正确引入。检查persistence.xml的位置
确保配置文件放在src/main/resources/META-INF/目录下(测试环境放在src/test/resources/META-INF/),Maven默认只会加载该路径下的persistence.xml文件。确认持久化提供者类存在
验证org.hibernate.jpa.HibernatePersistenceProvider类是否在类路径中,该类属于hibernate-core依赖,若依赖缺失或版本不匹配会导致无法找到。测试环境类路径排查
运行测试时,确保surefire插件能加载到persistence.xml和Hibernate依赖。可在测试代码中添加调试代码,查看可用的持久化提供者:System.out.println("Available persistence providers: " + Persistence.getProviders());若输出为空,说明类路径中无任何持久化提供者,核心原因是依赖缺失。
JDK与Hibernate版本兼容性
确认Hibernate版本与JDK版本匹配:Hibernate 5.x支持JDK 8+,若使用JDK 17+建议升级到Hibernate 6.x版本,同时调整persistence.xml的JPA版本为3.0。
内容的提问来源于stack exchange,提问作者Charly

