Search code examples
spring-bootrestmavenspring-data-mongodbioc-container

spring boot @repository bean from Maven dependency not found


I'm working on multiple Spring Boot projects using spring-data-mongoDB (w/o JPA). One that contains the common (udc-common) components, repositories and services and others (eg udc-gateway) that use these components. the udc-common library is declared as a maven dependency in the other projects. (you'll find enclosed the maven detailed configurations at the end of this post)

Environment structure

udc_common project

udc_common.models
udc_common.repositories
udc_common.services
udc_common.interfaces

udc_gateway project

udc_gateway.controllers
udc_gateway ....

gatewayApplication.java

gateway pom.xml

<dependency>
    <groupId>org.open_si</groupId>
    <artifactId>udc-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

in the udc-gateway project I have a rest controller thats refers to a udc-comm SampleService. When running it I face an error

Parameter 0 of constructor in org.open_si.udc_common.services.SampleService required a bean of type 'org.open_si.udc_common.repositories.SampleRepository' that could not be found.

the coding organization is :

  • the controller (SamplesController) belongs to the gateway project

  • the service (SampleService) and its repository (SampleRepository) belong to the common project being declared as maven dependency in the gateway project

Obviously the SampleService injection does work but its SampleRepository dependency doesn't. As the common package is an external one I've set the @componentscan accordingly in the gateway app main class

tryed

@ComponentScan("org.open_si.udc_common")

and

@ComponentScan({
        "org.open_si.udc_common.repositories",
        "org.open_si.udc_common.services"
})

the SamplesController (gateway project) code excerpt related for the SampleService is

@RestController
@RequestMapping("/samples")
public class SamplesController {

    @Autowired
    private SampleService service;
......

the SampleService (common project) is

@Service
@EnableMongoRepositories
public class SampleService {

    @Autowired
    private SampleRepository sr;

    void insert(BaseSampleEntity sample) {
        this.sr.insert(sample);
    }
    public void delete(BaseSampleEntity sample) {
        this.sr.delete(sample);
    }
.....

or also tryed

@Service
@EnableMongoRepositories
public class SampleService {

    private final SampleRepository sr;

    public SampleService(SampleRepository repository) {
        sr = repository;
    }

    void insert(BaseSampleEntity sample) {
        this.sr.insert(sample);
    }
    public void delete(BaseSampleEntity sample) {
        this.sr.delete(sample);
    }

and the SampleRepository (common project) is

// @Repository (JPA only)
public interface SampleRepository extends MongoRepository<BaseSampleEntity, String> {

    List<BaseSampleEntity> findByNodeUuid(String Uuid, Sort sort, Pageable pageable);

    List<BaseSampleEntity> findByFieldUuid(String Uuid, Sort sort, Pageable pageable);

so the raised exception

Parameter 0 of constructor in org.open_si.udc_common.services.SampleService required a bean of type 'org.open_si.udc_common.repositories.SampleRepository' that could not be found.

leads me thinking that something is wrong in the spring boot IOC process. Any idea ?

thanks in advance for your help.


udc-common pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>org.open_si</groupId>
    <artifactId>udc-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>UDC common</name>
    <packaging>jar</packaging>
    <description>Common resources for Universal Data Collector</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
<!--                    <source>1.8</source>-->
<!--                    <target>1.8</target>-->
                    <release>11</release>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

udc-gateway pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.open_si</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>Gateway</name>
    <description>Gateway for UDC project</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.open_si</groupId>
            <artifactId>udc-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-oauth2-client</artifactId>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Solution

  • Try adding below annotation in the spring boot main application class (ie. class annotated with SpringBootApplication - GateWayApplication.java)

    @EnableMongoRepositories(basePackages = "org.open_si.udc_common")
    @ComponentScan("org.open_si.udc_common.services")
    @EntityScan(basePackages ="org.open_si.udc_common.models") 
    

    Also, as you mentioned you don't need to annotate repository class with @Repository as this is already managed by spring data

    UPDATE: @SpringBootApplication itself has ComponentScan annoation embedded to it, so it automatically scans all the classes under all the subdirectories.

    Hope you have the directory structure somewhat similar to

    com.example
    --controllers
        -- SamplesController
    --service
        -- SampleService
    SampleApplication (this is the class that contains @SpringBootApplication & @EnableMongoRepositories)