You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot2.7.2升3.2.0+Java8转17时@DependsOnDatabaseInitialization循环依赖问题

Spring Boot 3.2.0 + Java 17 迁移问题解决

一、循环依赖问题(webSecurityConfig → ... → jpaSharedEM_entityManagerFactory ↔ dataSourceScriptDatabaseInitializer)

原因

Spring Boot 3.x 对数据库初始化组件(dataSourceScriptDatabaseInitializer)和JPA容器的依赖关系做了调整。当给依赖JPA Repository的bean(比如systemInitialService)添加@DependsOnDatabaseInitialization时,会强制该bean等待数据库脚本执行完成,但Repository代理的创建又依赖jpaSharedEM_entityManagerFactory,而EntityManagerFactory的初始化又依赖就绪的数据源,最终形成闭环依赖链。

正确解决方案(替代直接删除注解)

直接删除@DependsOnDatabaseInitialization会导致初始化逻辑提前执行(JPA容器未就绪),不是最优解。换用以下方式保证初始化时机:

  • 把systemInitialService里的初始化逻辑(比如默认用户创建)抽出来,放到CommandLineRunner或ApplicationListener<ContextRefreshedEvent>中:
    @Component
    public class SystemInitializer implements CommandLineRunner {
        private final UserRepository1 userRepository;
    
        public SystemInitializer(UserRepository1 userRepository) {
            this.userRepository = userRepository;
        }
    
        @Override
        public void run(String... args) throws Exception {
            // 原来的初始化逻辑,比如创建默认用户
            if (userRepository.findByUsername("admin").isEmpty()) {
                // 创建并保存默认用户逻辑
            }
        }
    }
    
  • 移除systemInitialService上的@DependsOnDatabaseInitialization注解,让Spring自动管理bean依赖,初始化逻辑会在整个应用上下文就绪后执行,既避开循环依赖,又保证数据库和JPA容器都已就绪。

二、无法解析jpaSharedEM_entityManagerFactory / SpringHibernateJpaPersistenceProvider未实现Jakarta接口问题

原因

Spring Boot 3.x 完全基于Jakarta EE规范(取代旧Java EE/Javax),要求Hibernate版本必须是6.0+(只有Hibernate 6.x才实现了jakarta.persistence.spi.PersistenceProvider接口)。触发该错误的常见场景:

  • 手动引入了Hibernate 5.x及以下版本的依赖
  • 第三方依赖间接引入了旧版Hibernate
  • 代码中残留javax.persistence相关引用

解决方案

  1. 依赖对齐:用Spring Boot Starter管理Hibernate版本
    删掉所有手动指定的hibernate-core、hibernate-entitymanager等依赖,直接使用spring-boot-starter-data-jpa,它会自动引入与Spring Boot 3.2.0兼容的Hibernate版本(6.4.x系列):
    <!-- pom.xml 中只保留这个,不要手动加Hibernate依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
  2. 排查依赖冲突
    用构建工具命令检查依赖树,找出引入旧版Hibernate的来源:
    • Maven:mvn dependency:tree | grep hibernate
    • Gradle:./gradlew dependencies | grep hibernate
      找到后通过exclusions排除旧版依赖,比如:
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>old-third-party-lib</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  3. 全局替换JPA引用为Jakarta
    把代码中所有javax.persistence.*的导入替换为jakarta.persistence.*,包括实体类、Repository接口、自定义注解等,避免残留的javax引用导致兼容性问题。

内容的提问来源于stack exchange,提问作者Subodh Joshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:16:10