'Parameter 0 of constructor in 'Controller' required a bean of type 'service' that could not be found. Not working: adding annotations, componentscans

I'm trying to use Services and DTOs in my project (trying to learn what they are and how they should be used). First, I had only Controllers, Models and Repository. The backend worked as expected. Then, I thought I'd use DTOs and Services to interface the client with the repo. But my app did not work afterwards.

The project structure: Project Structure

The MovieController:

package movie_API.movie.controllers;

import movie_API.movie.services.MovieService;
import movie_API.movie.services.beans.MovieDTO;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Controller
//@RequestMapping("/something") <- if you want a general something before the other resources
public class MovieController {

    private final MovieService movieService;

    public MovieController(MovieService movieService) {
        this.movieService = movieService;
        System.out.println("build controller");
    }

    @GetMapping("/movies")
    public String movies(Model model) {
        System.out.println("before getting in");
        movieService.showMovies(model);
        System.out.println("after getting in");

        return "movie/movies-all";
    }
 }

The Movie Model + the corresponding constructors and getters and setters:

package movie_API.movie.models;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Movie {

    private String id;
    private String metascore;
    private String title;
    private String year;
    private String description;
    private String genreId;

The MovieRepository:

package movie_API.movie.repositories;

import movie_API.movie.models.Movie;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public interface MovieRepository extends JpaRepository<Movie, String> {

    default ArrayList<String> getGenreNames(List<Movie> movies, GenreRepository genreRepository) {
        ArrayList<String> genreNames = new ArrayList<>();
        String genreIdInMovie;
        String genreName;
        for (Movie m : movies) {
            genreIdInMovie = m.getGenreId();
            genreName = genreRepository.findById(genreIdInMovie).get().getName();
            genreNames.add(genreName);
        }
        return genreNames;
    }
}

The MovieService:

package movie_API.movie.services;

import movie_API.movie.models.Movie;
import movie_API.movie.repositories.GenreRepository;
import movie_API.movie.repositories.MovieRepository;
import movie_API.movie.services.beans.MovieDTO;
import org.jvnet.hk2.annotations.Service;
import org.springframework.ui.Model;

import java.util.List;

@Service
public class MovieService {

    private final MovieRepository movieRepository;
    private final GenreRepository genreRepository;
    private List<Movie> movies;
    private Movie movie;

    public MovieService(MovieRepository movieRepository, GenreRepository genreRepository) {
        this.movieRepository = movieRepository;
        this.genreRepository = genreRepository;
    }

    public void showMovies(Model m) {

        m.addAttribute("allMovies", getMovies());
        m.addAttribute("allGenres", getGenreNames());

    }
}

The MovieDTO + corresponding constructor and getters and setters:

package movie_API.movie.services.beans;

import java.io.Serializable;

public class MovieDTO implements Serializable {

    private static final long serialVersionUID = -8040351309785589042L;

    private String id;
    private String metascore;
    private String title;
    private String year;
    private String description;
    private String genreId;

The MovieApplication:

package movie_API.movie;

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

@SpringBootApplication
public class MovieApplication {

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

}

The problem is that I receive an error saying that there is no bean called MovieService.

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-08-03 14:41:28.664 ERROR 3504 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Parameter 0 of constructor in movie_API.movie.controllers.MovieController required a bean of type 'movie_API.movie.services.MovieService' that could not be found.


Action:

Consider defining a bean of type 'movie_API.movie.services.MovieService' in your configuration.


Process finished with exit code 1

After researching this matter, I found several solutions recommended:

  • Apparently, it is not reading the bean from the package, therefore I tried to specifically ask it to scan the component services by changing to @SpringBootApplication(scanBasePackages={"movie_API.movie.services"}). This worked in the sense that I didn't receive the "Failed to start" error anymore. But now the problem was that the Controller wasn't accessed anymore. All calls were returned by "404 Not found" and the prints I put in the Controller weren't called. I tried to put all packages in the list, but the "Failed to start" error returned.
  • Another solution was to double check whether the MovieRepository and the MovieService had the annotations @Repository and @Service. These were there initially as well, so it didn't help.
  • I also tried to make the MovieService in the MovieController to be outside the constructor and be autowired. Still the same problem (no bean).


Solution 1:[1]

You imported the wrong Service annotation in your MovieService class. The one you should import is: import org.springframework.stereotype.Service;

Solution 2:[2]

Step 1) Check the ServiceImpl class.

Step 2) Attach @Service to ServiceImpl class.

Step 3) Problem is solved now.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Máté T?sér
Solution 2 Ankit