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,就得明说用谁


原始标题:Hibernate Error “No Persistence Provider for EntityManager” | Baeldung