Spring boot не находит JpaRepositories в sibling-пакете при использовании @ComponentScan или не может инициализировать их при использовании @EnableJpaRepositories

У меня есть проект Maven, состоящий из нескольких модулей. Три из этих модулей

  • "project-core" (содержит классы моделей)
  • "данные проекта" (содержит репозитории Spring Data JPA)
  • "project-spring" (содержит основное приложение Spring Boot с контроллерами REST).

При запуске я получаю следующее исключение:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.foo.bar.data.OrderRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Я знаю, что Spring Boot Applications по умолчанию просматривает только свои собственные и дочерние пакеты для bean-компонентов, но в этом случае bean-компонент находится в одноуровневом пакете. Я уже пытался добавить @ComponentScan({"org.foo.bar.data"}) в классе приложения, но безрезультатно.

С помощью @EnableJpaRepositories(basePackages = {"org.foo.bar.data"}) бросает

Caused by: java.lang.IllegalArgumentException: Not an managed type: class org.foo.bar.core.model.Order

Что я делаю неправильно?

Дерево каталогов (обрезанное) выглядит так:

project
├── project-core
│   └── src
│       └── main
│           └── java
│               └── org
│                   └── foo
│                       └── bar
│                           └── core
|                               └── model
|                                   └── Order.java
├── project-data
│   └── src
│       └── main
│           └── java
│               └── org
│                   └── foo
│                       └── bar
│                           └── data
|                               └── OrderRepository.java
│
└── project-spring
    └── src
        └── main
            └── java
                └── org
                    └── foo
                        └── bar
                            └── spring
                                └── Application.java

OrderRepository:

public interface OrderRepository extends JpaRepository<Order, Integer> {
    List<Order> findByDeliveryOverview(DeliveryOverview deliveryOverview);
    List<Order> findByDeliveryOverviewAndCustomer(DeliveryOverview deliveryOverview, Customer customer);
}

Application.java

@SpringBootApplication
@ComponentScan({"org.foo.bar.data"})
public class Application {
    private static final Logger log = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2 ответа

Решение

Основная проблема - ваша структура.

Для сканирования сущностей вам нужен @EntityScan в вашем классе приложения и для включения нужных вам репозиториев @EnableJpaRepositories,

@SpringBootApplication
@EntityScan({"org.foo.bar.core.model"})
@EnableJpaRepositories(basePackages = {"org.foo.bar.data"})
public class Application { ... }

Однако я бы предложил переместить Application класс для org.foo.bar и тогда вам нужно только @SpringBootApplication как он начнет сканирование из этого каталога.

Аннотировать OrderRepository с @Repository и удалите это утверждение {"org.foo.bar.data"} в @ComponentScan

Другие вопросы по тегам