Spring Boot启动时同一Repository接口生成两个重复Bean报错
问题根因
报错的核心原因是Spring Data JPA 与 Spring Data JDBC 两个数据模块的Repository扫描规则同时生效,两个模块都将你定义的IMyRepository识别为自身需要托管的Repository组件,先后尝试注册同名Bean。Spring Boot默认禁止Bean覆盖,因此启动中断。
你代码中继承的CrudRepository是Spring Data所有数据模块共用的顶层接口,没有明确的模块归属标识,JPA和JDBC的扫描器在全局包扫描时都会匹配到该接口,最终导致重复注册。
可直接落地的解决方案
根据你的项目实际场景选对应方案即可:
- 方案1:项目仅使用JPA作为持久层框架(绝大多数Spring Boot数据访问场景)
这种情况一般是JDBC相关依赖被其他starter传递引入,你本身不需要使用Spring Data JDBC,直接关闭JDBC Repository的自动注册即可,二选一操作:- 在
application.yml配置文件中添加如下配置:
- 在
spring: data: jdbc: repositories: enabled: false
- 在启动类上排除JDBC Repository的自动配置类:
@SpringBootApplication(exclude = JdbcRepositoriesAutoConfiguration.class) public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }
- 方案2:项目同时使用JPA和JDBC两种持久层技术
这种情况需要给两类Repository划定独立的扫描范围,避免交叉识别:- 调整目录结构,将JPA Repository统一放在
repository.jpa包下,JDBC Repository统一放在repository.jdbc包下 - 在启动类上明确指定两个模块的扫描路径:
- 调整目录结构,将JPA Repository统一放在
@SpringBootApplication @EnableJpaRepositories(basePackages = "com.package.api.**.repository.jpa") @EnableJdbcRepositories(basePackages = "com.package.api.**.repository.jdbc") public class ApiApplication { public static void main(String[] args) { SpringApplication.run(ApiApplication.class, args); } }
- 方案3:不想调整包结构,直接给Repository明确模块归属
直接将接口继承的通用CrudRepository替换为JPA专属的JpaRepository,JDBC扫描器会自动跳过带明确JPA标识的接口,示例代码:
package com.package.api.components.account.repository; import com.package.api.components.account.entity.Account; import org.springframework.data.jpa.repository.JpaRepository; public interface IMyRepository extends JpaRepository<Account, Long> { Account findByEmail(String email); Account findByEmailAndPassword(String email, String password); }
额外提示:不需要在Repository接口上额外添加
@Repository注解,Spring Data模块在扫描到符合规则的接口时会自动将其注册为Bean,额外加注解不会产生额外作用,反而可能在部分版本中加剧扫描识别冲突。
内容的提问来源于stack exchange,提问作者Z-100
相关产品推荐
相关产品推荐

