Search code examples
springspring-bootspring-data-jpaderbylombok

spring boot fails to start-- define a bean of type 'TopicRepository' in configuration


I was following this JavaBrains tutorials of Spring Boot.

My project structure is as follows:

enter image description here

CourseApiApp.java:

@SpringBootApplication
@ComponentScan(basePackages = {
    "com.bloodynacho.rishab.topics"
})
@EntityScan("com.bloodynacho.rishab.topics")
public class CourseApiApp {

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

TopicController.java:

@RestController
public class TopicController {

    @Autowired
    private TopicService topicService;

    @RequestMapping(
        value = "/topics"
    )
    public List<Topic> getAllTopcs() {
        return topicService.getAllTopics();
    }
}

TopicService.java:

@Service
public class TopicService {

    @Autowired
    private TopicRepository topicRepository;

    public List<Topic> getAllTopics() {
        List<Topic> topics = new ArrayList<>();
        this.topicRepository
            .findAll()
            .forEach(topics::add);
        return topics;
    }
}

Topic.java:

@Entity
public class Topic {
    @Id
    private String id;
    private String name;
    private String description;
}

TopicRepository.java:

@Repository
public interface TopicRepository extends CrudRepository<Topic, String>{
}

pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.derby</groupId>
        <artifactId>derby</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

I was using the lombok @Getter, @Getter and @AllArgsConstructor in Topic.java but I removed it after reading one of the answers here.

I read this1, this2, this3

Still, I get

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

Description:
Field topicRepository in com.bloodynacho.rishab.topics.TopicService required a bean of type 'com.bloodynacho.rishab.topics.TopicRepository' 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.bloodynacho.rishab.topics.TopicRepository' in your configuration.
Process finished with exit code 1

EDIT: I read this explaining how even without actually implementing the interface the @Autowired works. I understand the solution, but I don't understand how to solve my issue. Clearly, there is some problem with the way Spring Data is set up and configured (as mentioned in the answer)


Solution

  • Because if your other packages hierarchies are below your main application with the @SpringBootApplication annotation, you’re covered by implicit components scan.

    Therefore, one simple solution can be done by following 2 steps:

    1. Rename the package of main class to be com.bloodynacho.rishab.
      (That is what I suggest that the complete package name of main app. is supposed to be root of other packages.)
    2. Remove @ComponentScan and @EntityScan annotation.
      (Although @ComponentScan is different from @EntityScan, it can be also removed in my experience.)