1. 引言
本文将解析一个在使用 Hibernate 时常见的错误:“No persistence provider for EntityManager”。这个错误说白了就是:JPA 不知道该用哪个实现来完成对象的持久化。
这里的 persistence provider(持久化提供者) 指的就是具体的 JPA 实现,比如 Hibernate、EclipseLink 等。你的应用必须明确告诉 JPA:“我用的是 Hibernate”,否则它就懵了。
如果你对 JPA 和它的各种实现之间的区别还不太清楚,建议先补一补基础知识,比如我们之前写的《JPA、Hibernate 与 EclipseLink 的区别》这类文章。
2. 错误原因分析
这个错误的核心原因是:应用没有指定使用哪个持久化提供者。
具体触发场景通常有以下两种:
✅ 你在 persistence.xml
中没有配置 <provider>
标签
✅ 或者你手动实现了 PersistenceUnitInfo
接口,但没重写 getPersistenceProviderClassName()
方法
JPA 启动时会去查找对应的 provider,如果找不到,就会抛出这个经典异常。
⚠️ 注意:即使你项目里已经引入了 Hibernate 的依赖,但如果没显式声明 provider,JPA 依然可能无法自动识别——尤其是在非 Spring 环境下。
3. 解决方案
3.1 在 persistence.xml
中指定 Provider
最简单粗暴的办法,就是在 persistence.xml
文件中明确写出你要用的持久化实现类。
对于 Hibernate 5.x 及以上版本(含 6.x):
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="my-pu">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- 其他配置 -->
</persistence-unit>
</persistence>
如果你还在用 Hibernate 4.2 或更老版本:
<provider>org.hibernate.ejb.HibernatePersistence</provider>
❗ 注意包名变化:老版本是
ejb
,新版本是jpa
,别搞混了,否则照样报错。
3.2 手动实现 PersistenceUnitInfo
时的处理
有些高级场景下,你可能会自己实现 PersistenceUnitInfo
接口来动态构建持久化单元。这时候必须记得重写这个方法:
@Override
public String getPersistenceProviderClassName() {
return org.hibernate.jpa.HibernatePersistenceProvider.class.getName();
}
否则 JPA 依然不知道该用哪个 provider,踩坑无数。
3.3 确保依赖完整
光写配置没用,还得确保 classpath 下有对应的 Hibernate 核心 jar 包。Maven 项目请检查 pom.xml
是否包含:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.5.2.Final</version>
</dependency>
✅ 建议:使用最新稳定版,避免因版本兼容问题引发连锁异常。
📌 小贴士:如果你用的是 Spring Boot,一般不需要手动配 provider,因为 spring-boot-starter-data-jpa
已经帮你自动配置好了。但如果是纯 JPA + Hibernate 的原生环境,这一步绝对不能少。
4. 总结
问题 | 解法 |
---|---|
缺少 persistence provider 配置 | 在 persistence.xml 添加 <provider> |
使用旧版 Hibernate | 注意使用 org.hibernate.ejb.HibernatePersistence |
自定义 PersistenceUnitInfo |
必须重写 getPersistenceProviderClassName() |
依赖缺失 | 添加 hibernate-core 到 classpath |
遇到 “No persistence provider for EntityManager” 不用慌,99% 的情况都是 provider 没声明清楚。按上面几步排查,基本都能快速定位解决。
✅ 记住一句话:谁实现的 JPA,就得明说用谁。