# Springboot 应用中@EntityScan 和@EnableJpaRepositories 的用法

在 Springboot 应用开发中使用 JPA 时,通常在主应用程序所在包或者其子包的某个位置定义我们的 Entity 和 Repository,这样基于 Springboot 的自动配置,无需额外配置,我们定义的 Entity 和 Repository 即可被发现和使用。

但有时候我们需要定义 Entity 和 Repository 不在应用程序所在包及其子包,那么这时候就需要使用@EntityScan 和@EnableJpaRepositories 了。

上面提到的 Entity 和 Repository 指的是通过类似下面的方式定义的 Entity 和 Repository :

实体定义

@Entity
@Table(name = "grade")
public class Grade {
   // 省略具体内容
}

repository 对象

@Repository
public interface GradeRepository extends JpaRepository<Grade, Long>, JpaSpecificationExecutor<Grade> {
   // 省略具体内容
}

# @EntityScan

@EntityScan 用来扫描和发现指定包及其子包中的 Entity 定义。其用法如下:

@EntityScan(basePackages = {"com.department.entities","come.employee.entities"})

如果多处使用@EntityScan,它们的 basePackages 集合能覆盖所有被 Repository 使用的 Entity 即可,集合有交集也没有关系。但是如果不能覆盖被 Repository 使用的 Entity,应用程序启动是会出错,比如:

Not a managed type: com.customer.entities.Customer

# @EnableJpaRepositories

@EnableJpaRepositories 用来扫描和发现指定包及其子包中的 Repository 定义。其用法如下:

@EnableJpaRepositories(basePackages = {"com.department.repositories","come.employee.repositories"})

如果多处使用@EnableJpaRepositories,它们的 basePackages 集合不能有交集,并且要能覆盖所有需要的 Repository 定义。

如果有交集,相应的 Repository 会被尝试反复注册,从而遇到如下错误:

The bean ‘OrderRepository’, defined in xxx, could not be registered. A bean with that name has already been defined in xxx and overriding is disabled.

如果不能覆盖所有需要的 Repository 定义,会遇到启动错误:

Parameter 0 of method setCustomerRepository in com.service.CustomerService required a bean of type ‘come.repo.OrderRepository’ that could not be found.