1

I'm working on a Spring Boot multi-module project. I have created separate modules as follows

  • com.foodshop.api - (this is a Spring Boot project, the starting point and both com.foodshop.application and com.foodshop.persistence are added as dependencies here)
  • com.foodshop.application - (the application layer where I have the business logic, thi s is a library project and spring-boot-starter and com.foodshop.persistence are added as dependencies here)
  • com.foodshop.persistence - (this is where the repositories defined, spring-boot-starter-data-mongodb is added as a dependency in this project)

All 3 project mentioned above are wrapped inside a parent pom maven project and the parent pom.xml looks as follows;

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.foodshop</groupId>
    <artifactId>foodshop-backend</artifactId>
    <version>0.0.1</version>
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <modules>
        <module>foodshop.persistence</module>
        <module>foodshop.application</module>
        <module>foodshop.api</module>
    </modules>
</project>

The project builds without any errors. The application class of foodshop.api I have annotated as follows so that it can see the dependencies in other modules

@SpringBootApplication(scanBasePackages = {"com.foodshop"})

But when I try to run the API project, it looks like the foodshop.application fails to find and autowire the repositories defined in foodshop.persistence

I get an error as follows;

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.foodshop.application.MealManager required a bean of type 'com.foodshop.persistence.repository.MealRepository' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.foodshop.persistence.repository.MealRepository' in your configuration.

I have properly annotated MealRepository with the @Repository annotation but I feel like I have missed something important.

It would be very much appreciated if I can get some help on this issue.

PIKP
  • 753
  • 2
  • 15
  • 24
  • And it's supposed that you annotated the 'com.foodshop.persistence.repository.MealRepository' bean, right? – Evgeni Enchev Apr 01 '22 at 06:22
  • Yes, you are correct @EvgeniEnchev – PIKP Apr 01 '22 at 07:05
  • Just to be clear - you set the `@Repository` annotation on the implementation of the `com.foodshop.persistence.repository.MealRepository`, not on the interface. I had some errors and spent lot of time looking at the code when the annotation was not on the right place. – Evgeni Enchev Apr 01 '22 at 07:13
  • @EvgeniEnchev Just to be clear - this is what I have done; `@Repository public interface MealRepository extends MongoRepository { }` I don't see a need to implement a repository since I'm using Spring Data so I have annotated the Interface. Have I done something that I shouldn't have done? – PIKP Apr 01 '22 at 07:21
  • Everything looks fine. Sorry, about the questions, didn't mention you use spring-data. – Evgeni Enchev Apr 01 '22 at 07:28

1 Answers1

2

After more than 20 hours reading and following the trial and error approach, I was able to identify the issue. As per the Spring official documentations

If your application also uses JPA or Spring Data, the @EntityScan and @EnableJpaRepositories (and related) annotations inherit only their base package from @SpringBootApplication when not explicitly specified. That is, once you specify scanBasePackageClasses or scanBasePackages, you might also have to also explicitly use @EntityScan and @EnableJpaRepositories with their package scans explicitly configured.

Since I use spring-boot-starter-data-mongodb, I annotated my Application class as follows;

@SpringBootApplication(scanBasePackages = {"com.foodshop"})
@EnableMongoRepositories(basePackages = "com.foodshop.persistence")
public class Application {
  // main method goes here.
}

@EnableMongoRepositories annotation did the trick.

PIKP
  • 753
  • 2
  • 15
  • 24