Home > Back-end >  How to fix this issue "Consider defining a bean of type 'repository.InterfaceName' in
How to fix this issue "Consider defining a bean of type 'repository.InterfaceName' in

Time:09-18

I am using IntelliJ to learn spring boot and I encountered this issue when running the code

2021-09-05 12:55:48.665 ERROR 10396 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Parameter 0 of constructor in service.EmployeeService required a bean of type 'repository.EmployeeRepository' that could not be found.


Action:

Consider defining a bean of type 'repository.EmployeeRepository' in your configuration.


Process finished with exit code 0

the project files tree looks like this:

├── HELP.md
├── mvnw
├── mvnw.cmd
├── my-first-project.iml
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── com
│   │   │   │   └── firstproject
│   │   │   │       └── myfirstproject
│   │   │   │           └── MyFirstProjectApplication.java
│   │   │   ├── controller
│   │   │   │   └── EmployeeController.java
│   │   │   ├── model
│   │   │   │   └── Employee.java
│   │   │   ├── repository
│   │   │   │   └── EmployeeRepository.java
│   │   │   └── service
│   │   │       └── EmployeeService.java
│   │   └── resources
│   │       ├── application.properties
│   │       ├── static
│   │       └── templates
│   └── test
│       └── java
│           └── com
│               └── firstproject
│                   └── myfirstproject
│                       └── MyFirstProjectApplicationTests.java
└── target
    ├── classes
    │   ├── application.properties
    │   ├── com
    │   │   └── firstproject
    │   │       └── myfirstproject
    │   │           └── MyFirstProjectApplication.class
    │   ├── controller
    │   │   └── EmployeeController.class
    │   ├── model
    │   │   └── Employee.class
    │   ├── repository
    │   │   └── EmployeeRepository.class
    │   └── service
    │       └── EmployeeService.class
    ├── generated-sources
    │   └── annotations
    ├── generated-test-sources
    │   └── test-annotations
    └── test-classes
        └── com
            └── firstproject
                └── myfirstproject
                    └── MyFirstProjectApplicationTests.class

EmployeeController:

package controller;

import model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import service.EmployeeService;

import java.util.List;

@RestController
@RequestMapping(path = "/api/v1/employee")
public class EmployeeController {

    private final EmployeeService employeeService;

    @Autowired
    public EmployeeController(EmployeeService employeeService) {

        this.employeeService = employeeService;
    }
    @GetMapping
    public List<Employee> getEmployee(){
        return employeeService.getEmployee();
    }
}

EmployeeService :

package service;

import model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import repository.EmployeeRepository;

import java.util.List;


@Service
public class EmployeeService {

    final EmployeeRepository employeeRepository;
    @Autowired
    public EmployeeService(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }

    @GetMapping
    public List<Employee> getEmployee(){

        return employeeRepository.findAll();
    }

}

Employee :

package model;

import javax.persistence.*;
import java.time.LocalDate;
@Entity
@Table
public class Employee {
    @Id
    @SequenceGenerator(name = "emp_sequence",
    sequenceName = "emp_sequence",
    allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "emp_sequence")
    private Long id;
    private String name;
    private String email;
    private LocalDate dob;
    private Float salary;

    public Employee() {
    } ...\\Getters and Setters

EmployeeRepository :

package repository;

import model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long> {

}

MyFirstProjectApplication:

package com.firstproject.myfirstproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;



@SpringBootApplication(scanBasePackages = {"repository","controller","service","model"})
//I added scanBasePackages = {"repository","controller","service","model"} because i hade the same problem with other packages and it solved it except for repository
public class MyFirstProjectApplication {

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

}

the application properties :

spring.datasource.url=jdbc:postgresql://localhost:5432/employee
spring.datasource.username=postgres
spring.datasource.password=*********
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.open-in-view=false

And Finaly the 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.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.firstproject</groupId>
    <artifactId>my-first-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-first-project</name>
    <description>my-first-project</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <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.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-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>

I am using:

  • java 11
  • spring boot (v2.5.4)
  • Intellij IDEA 2021.2.1 ultimate edition

I had the same problem with other packages but adding @SpringBootApplication(scanBasePackages = {"controller","service","model"}) solved the issue for them.

CodePudding user response:

Well annotation scanning for Spring does not include the package repository so it does not scan the @Repository to add it as a spring bean. You ned to also define

@SpringBootApplication(scanBasePackages = {"controller","service","model", "repository"})

Reason for that is that the default package that spring scanns is the com.firstproject.myfirstproject where the MyFirstProjectApplication.claass exists which defines the main method that starts the spring boot application.

Considering that all other packages are outside of that package you need to define them manualy with scanBasePackages in order for spring to get inside those other packages like service, repository and scan for annotations and make neccessary actions.

CodePudding user response:

Move the packages controller, repository, model and service to com.firstproject.myfirstproject. With this you may get rid of scanBasePackages = {"controller","service","model"} and use only @SpringBootApplication as follows:

package com.firstproject.myfirstproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyFirstProjectApplication {

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

@SpringBootApplication encapsulates @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations with their default attributes. The default value for @ComponentScan means that all the sub packages on the package the @ComponentScan is used are scanned. That is why it is usually a good practice to include the main class in the base package of the project.

  • Related