SpringBoot整合Hibernate JPA报错未实现PersistenceProvider接口
Spring Boot整合JPA启动报错:PersistenceProvider接口未实现
报错信息
项目启动抛出精简后错误:
Class org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider does not implement the requested interface javax.persistence.spi.PersistenceProvider
问题根因
所有报错都来自依赖版本冲突和配置错误,无特殊玄学问题:
- 版本体系不兼容:Spring Boot 2.7.1属于Java EE生态,所有持久层接口使用
javax.*前缀,适配Hibernate 5.6.x系列;但手动指定的Hibernate 6.1.0.Final已经切换到Jakarta EE生态,接口全是jakarta.*前缀,和Spring自带的JPA适配类完全无法匹配。 - 类路径存在重复JPA接口:同时引入了
javax.persistence-api 2.2和jakarta.persistence-api 3.0.0两套JPA规范包,类加载时拿到的接口和实现类不属于同一套规范,自然会报"不实现接口"的错误。 - Spring组件版本不匹配:手动指定的
spring-orm 5.3.2和Spring Boot 2.7.1自带的Spring 5.3.21版本差了十几个小版本,JPA相关的适配逻辑存在差异。 - 配置笔误:启动类写死的包扫描路径是
com.draconia.testWeb.controller,但实际所有代码都在net.draconia.testWeb包下,就算解决依赖问题也扫不到自定义的Bean。
修复步骤
按顺序改完就能正常启动,不需要额外调整业务逻辑:
- 修正pom.xml依赖
- 删掉properties标签下手动定义的
hibernate.version、spring.version两个配置,Spring Boot父工程已经默认管理了所有官方依赖的兼容版本,手动指定很容易凑出不兼容的版本组合。 - 删掉多余/冲突的依赖:
jakarta.persistence:jakarta.persistence-api:3.0.0javax.persistence:javax.persistence-api:2.2- 手动指定版本的
org.springframework:spring-orm:5.3.2 - 手动指定版本的
org.hibernate.orm:hibernate-core:6.1.0.Final - 单独引入的
jackson-core也可以删掉,spring-boot-starter-web已经自带了JSON序列化需要的所有Jackson包。
- 新增Spring Boot官方JPA启动器,它会自动引入和当前Boot版本完全兼容的Hibernate、spring-orm、JPA API,不需要自己逐个凑依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
- 删掉properties标签下手动定义的
- 修正数据源配置
你用的是MySQL 8.x版本,驱动类名已经不是旧版的com.mysql.jdbc.Driver,改成com.mysql.cj.jdbc.Driver;JDBC连接串加上时区参数避免运行时报时区错误,示例:objDatasource.setUrl("jdbc:mysql://localhost:3306/Test?serverTimezone=UTC&useSSL=false&characterEncoding=utf8"); - 精简启动类配置
引入JPA启动器后,Spring Boot会根据你配置的DataSource自动创建EntityManagerFactory、事务管理器、Hibernate适配器这些Bean,不需要手动写@Bean方法重复配置,反而容易因为配置不全出问题。
删掉启动类里的getEntityManagerFactory()、getHibernateTransactionManager()、getHibernateProperties()三个方法,只保留数据源的@Bean即可;同时把启动类上的注解改回默认的@SpringBootApplication,删掉写死的错误包扫描路径,启动类在根包下时Spring会自动扫描所有子包的组件。
如果要自定义Hibernate配置,直接在resources下新建application.properties写配置就行,比硬编码在Java类里好维护:spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect - 修正DAO和控制器代码
- DAO层不要自己手动调用
createEntityManager()新建实体管理器,Spring会自动管理EntityManager的生命周期和事务,直接用@PersistenceContext注入即可,避免手动创建不关闭导致数据库连接泄漏:@Repository("bookDAO") public class BookDAOImpl implements BookDAO { @PersistenceContext private EntityManager entityManager; @Override public List<Book> getAllBooks() { return entityManager.createQuery("from Books", Book.class).getResultList(); } } - 控制器类把
@Controller改成@RestController,@Controller默认会走视图解析,不会直接把返回的List序列化成JSON响应。
- DAO层不要自己手动调用
改完之后刷新Maven依赖,重新启动项目就能正常访问/Books接口。
内容的提问来源于stack exchange,提问作者Seth D. Fulmer
相关产品推荐
相关产品推荐

