183

So I've been learning Spring in the couples of week, been following this tutorial

Building a RESTful Web Service

All was well until I tried to integrate it to mongodb. So I follow this tutorial.

Accessing Data with MongoDB

But my practice is partially still using the first one. So my project directory structure is like this.

src/
├── main/
│   └── java/
|       ├── model/
|       |   └── User.java
|       ├── rest/
|       |   ├── Application.java
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── service/
|           └── UserService.java
└── resources/
    └── application.properties

This is my model/User.java file

package main.java.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="user")
public class User {

    private int age;
    private String country; 
    @Id
    private String id;
    private String name;


    public User() {
        super();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}

This is my rest/UsersController.java file

package main.java.rest;

import java.util.List;
import main.java.service.UserService;
import main.java.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/users")
public class UsersController {

    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET)
    public List<User> getAllUsers() {
        return userService.findAll();
    }
}

This is my service/UserService.java file

package main.java.service;

import java.util.List;
import main.java.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserService extends MongoRepository<User, String> {
    public List<User> findAll();
}

I could compile them (I'm using gradle for compilation because I'm following the tutorial), but when I run the jar file it was throwing this error.


APPLICATION FAILED TO START


Description:

Field userService in main.java.rest.UsersController required a bean of type 'main.java.service.UserService' that could not be found.

Action:

Consider defining a bean of type 'main.java.service.UserService' in your configuration.

Not sure what is wrong I start googling around and found that I need to include Beans.xml file and register the userService in it. I did that but it's not working. I'm really new to this so I really have no clue on what's going on.

Eka Rudianto
  • 4,435
  • 4
  • 15
  • 23

38 Answers38

223

Solved it. So by default, all packages that falls under @SpringBootApplication declaration will be scanned.

Assuming my main class ExampleApplication that has @SpringBootApplication declaration is declared inside com.example.something, then all components that falls under com.example.something is scanned while com.example.applicant will not be scanned.

So, there are two ways to do it based on this question. Use

@SpringBootApplication(scanBasePackages={
"com.example.something", "com.example.application"})

That way, the application will scan all the specified components, but I think what if the scale were getting bigger ?

So I use the second approach, by restructuring my packages and it worked ! Now my packages structure became like this.

src/
├── main/
│   └── java/
|       ├── com.example/
|       |   └── Application.java
|       ├── com.example.model/
|       |   └── User.java
|       ├── com.example.controller/
|       |   ├── IndexController.java
|       |   └── UsersController.java
|       └── com.example.service/
|           └── UserService.java
└── resources/
    └── application.properties
Nick
  • 617
  • 1
  • 7
  • 22
Eka Rudianto
  • 4,435
  • 4
  • 15
  • 23
134

Add the @Service in the service/UserService.java.

Simon H
  • 2,495
  • 4
  • 30
  • 38
dzzxjl
  • 1,441
  • 1
  • 9
  • 9
39

I also had the same error:

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

Description:

Field repository in com.kalsym.next.gen.campaign.controller.CampaignController required a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' that could not be found.


Action:

Consider defining a bean of type 'com.kalsym.next.gen.campaign.data.CustomerRepository' in your configuration.de here

And my packages were constructed in the same way as mentioned in the accepted answer. I fixed my issue by adding EnableMongoRepositories annotation in the main class like this:

@SpringBootApplication
@EnableMongoRepositories(basePackageClasses = CustomerRepository.class)
public class CampaignAPI {

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

If you need to add multiple don't forget the curly braces:

@EnableMongoRepositories(basePackageClasses
    = {
        MSASMSRepository.class, APartyMappingRepository.class
    })
shabby
  • 3,002
  • 3
  • 39
  • 59
32

I had the same problem I removed the @Autowired Annotation from the controller. If your repository is a class then the Autowired Annotation is needed to use the repository but when it is an interface you do not need to add the @Autowired Annotation from my experience.

Apostolos
  • 10,033
  • 5
  • 24
  • 39
mumbasa
  • 632
  • 7
  • 11
  • Works for me, thanks! – Seeschon Oct 14 '21 at 16:19
  • goddamn i've been stuck on this white page error for so long. I just removed the @Autowired annotation in my service class where I declared my jpaRepo interfaces. Saved the day. Thanks alot – Aryan Sethi Apr 22 '22 at 12:40
  • With all my order services this doesn't give a problem but for one certain class it did, and I had to remove the autowired. Really strange – Yannick Mussche Sep 12 '22 at 10:12
  • This specific solution worked for me, because I was autowiring an interface. – user1849060 Oct 07 '22 at 10:18
  • 2
    My Repository class is an interface. And I tried this, removing @Autowired from the declaration of the Repository class, but I got a null pointer exception. Is there something else that needs to be done to instantiate an instance of the repository? – Bradley D Jan 12 '23 at 13:56
  • Now I'm getting a null pointer exception, like @BradleyD – A B Jun 21 '23 at 09:41
29

You have to add the @Service annotation to the implementation of your service.

ColdFire
  • 1,301
  • 13
  • 14
21

Spent a lot of time because of the auto-import. Intellij Idea somewhy imported @Service from import org.jvnet.hk2.annotations.Service; instead of import org.springframework.stereotype.Service;!

Vitali
  • 549
  • 6
  • 16
  • Could you update your answer and explain what you are doing. Many thanks in advance – MZaragoza Dec 23 '17 at 13:47
  • @VitaliKuzmin still there is no clarity in your answer. Your answer may be correct and it may have worked for you but the way you presented here is confusing and not reader friendly – Suresh Jun 21 '18 at 08:39
  • 3
    @mannedear I think that my first comment answers yours' comment as well. – Vitali Jun 21 '18 at 12:52
  • +1'd this answer, as I made an import error as well! :0 `import javax.persistence.Table;` instead of `import org.springframework.data.relational.core.mapping.Table;` in my model. smh lost 5hrs in debugging this bean error. – kalpaj agrawalla Aug 03 '20 at 13:20
17

I encountered the same issue and all I had to do was to place the Application in a package one level higher than the service, dao and domain packages.

Akash Yellappa
  • 2,126
  • 28
  • 21
13

This thread is old now but I am posting my answer, which may be useful for others.

I had the same issue. It turned out that there is another class with the same name in other module. I renamed that class and it solved the issue.

12

In order to spring to create bean and inject it into the class, class should be marked with @Componet,@service or @Repository any one of the annotation, in your context it should be

package main.java.service;

import java.util.List;
import main.java.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
@Repository
public interface UserService extends MongoRepository<User, String> {
    public List<User> findAll();
}
noob
  • 349
  • 2
  • 8
  • I was getting this error even after keeping the bean under same package path. Adding `@Component` resolved the issue. [id 'org.springframework.boot' version '3.0.4'] – Gaurav Adurkar May 23 '23 at 05:27
9

I had the same issue. My mistake was that I used @Service annotation on the Service Interface. The @Service annotation should be applied to the ServiceImpl class.

Apostolos
  • 10,033
  • 5
  • 24
  • 39
Ashish Singh
  • 399
  • 4
  • 11
7

Normally we can solve this problem in two aspects:

  1. proper annotation should be used for Spring Boot scanning the bean, like @Component;
  2. the scanning path will include the classes just as all others mentioned above.

By the way, there is a very good explanation for the difference among @Component, @Repository, @Service, and @Controller.

Hearen
  • 7,420
  • 4
  • 53
  • 63
5

Add @Repository in you dao class

example:

@Repository
public class DaoClassName implements IIntefaceDao {
}
sonOFAthena
  • 108
  • 1
  • 6
4

Using all @ Annotations fixed my problem. (Yes, I'm new into Spring) If you are using a service class add @Service, and same for @Controller and @Repository.

Then this annotations on the App.java fixed the issue (I'm using JPA + Hibernate)

@SpringBootApplication
@EnableAutoConfiguration(exclude = { ErrorMvcAutoConfiguration.class })
@ComponentScan(basePackages = {"es.unileon.inso2"})
@EntityScan("es.unileon.inso2.model")
@EnableJpaRepositories("es.unileon.inso2.repository")

Package tree:

src/
├── main/
│   └── java/
|       ├── es.unileon.inso2/
|       |   └── App.java
|       ├── es.unileon.inso2.model/
|       |   └── User.java
|       ├── es.unileon.inso2.controller/
|       |   ├── IndexController.java
|       |   └── UserController.java
|       ├── es.unileon.inso2.service/
|       |    └── UserService.java
|       └── es.unileon.inso2.repository/
|            └── UserRepository.java
└── resources/
    └── application.properties
Kashmir54
  • 115
  • 1
  • 1
  • 8
4

you have to import spring-boot-starter-data-jpa as dependency if you use spring boot

Apostolos
  • 10,033
  • 5
  • 24
  • 39
duracell
  • 644
  • 8
  • 13
4

For anybody who was brought here by googling the generic bean error message, but who is actually trying to add a feign client to their Spring Boot application via the @FeignClient annotation on your client interface, none of the above solutions will work for you.

To fix the problem, you need to add the @EnableFeignClients annotation to your Application class, like so:

@SpringBootApplication
// ... (other pre-existing annotations) ...
@EnableFeignClients // <------- THE IMPORTANT ONE
public class Application {

In this way, the fix is similar to the @EnableMongoRepositories fix mentioned above. It's a shame that this generic error message requires such a tailored fix for every type of circumstance...

eriegz
  • 335
  • 3
  • 10
4

you can add @Service, when defining your service class

ex:

@Service
public class myService {

    public String getData(){
       return "some data";
    }

}
Apostolos
  • 10,033
  • 5
  • 24
  • 39
3

Add the @Component in your controller class. May this work

shubham bansal
  • 163
  • 1
  • 2
  • 9
3

You need to add to your main class a @ComponentScan annotation, telling it to scan the package of the services, otherwise it will not initialize these beans

Apostolos
  • 10,033
  • 5
  • 24
  • 39
Andre TOKAM
  • 183
  • 1
  • 7
2

I have same Issue, fixed by Adding @EnableMongoRepositories("in.topthree.util")

package in.topthree.core;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import in.topthree.util.Student;

@SpringBootApplication
@EnableMongoRepositories("in.topthree.util")
public class Run implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Run.class, args);
        System.out.println("Run");
    }

    @Autowired
    private Process pr;

    @Override
    public void run(String... args) throws Exception {
        pr.saveDB(new Student("Testing", "FB"));
        System.exit(0);
    }

}

And my Repository is:

package in.topthree.util;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface StudentMongo extends MongoRepository<Student, Integer> {

    public Student findByUrl(String url);
}

Now Its Working

Morteza Jalambadani
  • 2,190
  • 6
  • 21
  • 35
Ahmad
  • 41
  • 2
2

I have come to this post looking for help while using Spring Webflux with Mongo Repository.

My error was similar to owner

Field usersRepository in foobar.UsersService required
a bean of type 'foobar.UsersRepository' that could not be found.

As I was working before with Spring MVC I was surprised by this error.

Because finding help was not so obvious I'm putting answer to this question as it is somehow related and this question is high in search results.

First thing is you must remember about what was mentioned in answer marked as accepted - package hierarchy.

Second important thing is that if you use Webflux you need to use some different package while when using Spring MVC e.g. for MongoDB you need to add

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

with -reactive at the end.

Łukasz Kotyński
  • 1,007
  • 1
  • 9
  • 10
2

I was wondering problem for hours. The reason was this excluding command. I added this before for testing (then forgot). I am sure someone can make the same mistake.

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })

... change to fix:

@SpringBootApplication
1

This may happen when two beans have same names.

Module1Beans.java

@Configuration
public class Module1Beans {
    @Bean
    public GoogleAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.google.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GoogleAPI.class);
    }
}

Module2Beans.java

@Configuration
public class Module2Beans {
    @Bean
    public GithubAPI retrofitService(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.github.com/")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        return retrofit.create(GithubAPI.class);
    }
}

A bean named retrofitService is first created, and it's type is GoogleAPI, then covered by a GithubAPI becauce they're both created by a retrofitService() method. Now when you @Autowired a GoogleAPI you'll get a message like Field googleAPI in com.example.GoogleService required a bean of type 'com.example.rest.GoogleAPI' that could not be found.

benymor
  • 21
  • 1
1

My Mapper implementation classes in my target folder had been deleted, so my Mapper interfaces had no implementation classes anymore. Thus I got the same error Field *** required a bean of type ***Mapper that could not be found.

I simply had to regenerate my mappers implementations with maven, and refresh the project...

RotS
  • 2,142
  • 2
  • 24
  • 30
1

Add @Repository in your dao class

    @Repository
    public interface UserDao extends CrudRepository<User, Long> {
         User findByUsername(String username);
         User findByEmail(String email);    
      }
biddut
  • 353
  • 3
  • 6
1

Spent about 2 hours debugging this error then somewhat figured out I forgot to add Spring Web Mvc Dependency

   <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.9</version>
    </dependency>
karalis1
  • 205
  • 1
  • 12
0

In my case i have just put the Class MyprojectApplication in a package(com.example.start) with the same level of model, controller,service packages.

Zain Elabidine
  • 349
  • 5
  • 16
0

I know it is old, but wanna add my 5 cents.

I used .service and .service.impl in a folder structure to separate the service with it's implementation. Forget to implement the ServiceImplementation piece.

Cyber
  • 2,194
  • 4
  • 22
  • 41
0

For me this message:

org.apache.wicket.WicketRuntimeException: Can't instantiate page using constructor 'public org.package.MyClass(org.apache.wicket.request.mapper.parameter.PageParameters)' and argument ''. Might be it doesn't exist, may be it is not visible (public).

meant "in my wicket unit test at the top you have to manually add that bean in like"

appContext.putBean(myClass);
rogerdpack
  • 62,887
  • 36
  • 269
  • 388
0

I followed all steps and instructions followed by OP here, took care of blank space around username and password(even though spring takes care of whitespaces in properties file), still was either facing

could not find bean for ___Repository

(you interface which extends JPARepository)

OR after adding @EnableJPARepository

could not find bean for EntityManagerFactory

i solved it by changing spring boot starter parent version from 2.3.2 to 2.2.1 in pom.xml

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

and adding following dependency

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

I did not need to add any of following, spring boot does it itself

  1. @EnableJPAReposity - since i already had all class with same root package
  2. spring.data.jpa.repositories.enabled in application.properties
  3. spring.datasource.driverClassName=com.mysql.jdbc.Driver in application properties
0

Two types of mongo dependencies -

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency> 

Two types of repositories -

MongoRepository
ReactiveMongoRepository

Make sure you are using the right combination.

0

The class annotated with @SpringBootApplication should be in your root package (by default all classes in this package and subpackages are scanned) or you need to specify other packages (controller, entity and others) in @ComponentScan.

In order to create bean and inject it class in spring framework, Class should be marked with @Componet, @Service or @Repository in class level accordingly. Make sure you have used it.

enter image description here

Apostolos
  • 10,033
  • 5
  • 24
  • 39
anand krish
  • 4,281
  • 4
  • 44
  • 47
0

Putting this value in application.properties worked for me

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

Note that if your package structure is the same as that in the accepted answer, all you need is @SpringBootApplication annotation on your main class (no additional parameters inside it)

Source : Spring boot Field required a bean of type that could not be found

mnagdev
  • 384
  • 3
  • 11
0

For me adding dependency 'org.mongodb:mongodb-driver-sync:4.3.2' works perfectly. Didn't found that answer here.

Restonov
  • 21
  • 3
0

ONLY INTERESTING IF YOU TRY TO AUTOWIRE AN ABSTRACT CLASS!

You are running in to this issue because Spring Boot can't find an abstract class by default.

First, an abstract class isn't component-scanned since it can't be instantiated without a concrete subclass.

Means you have to create a subclass for this abstract class to solve the issue.

0

Faced same issue when initialise the gradle project in kotlin.

Reason: Actually it is not able to scan build.gradle.kts file.

Solution: We can add a @ComponentScan("build.gradle.kts") before the main function declaration so that it can go to the gradle file and scan all the required dependencies.

Procrastinator
  • 2,526
  • 30
  • 27
  • 36
Jatin
  • 13
  • 3
0

This error will happen when you add this ...

   <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
   </dependency>

instead of this...

   <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
   </dependency>

In your scenario remove the -reactive and the bean creation should work

rogger2016
  • 821
  • 3
  • 11
  • 28
-1

Using this solved my issue.

@SpringBootApplication(scanBasePackages={"com.example.something", "com.example.application"})
Lorelorelore
  • 3,335
  • 8
  • 29
  • 40
Anand
  • 183
  • 2
  • 7
-1

For those searching for the root cause of this error message, in my case it was due to a (JSON) file dependency not being loaded for a Spring (Bean) Configuration class. Set up like so:

package my.package;

import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class MyConfiguration {

    @Autowired
    FileHelperUtils fileHelperUtils;

    @Bean
    public MyMappingResponse getMyMappings() throws IOException {
        String jsonResponse = fileHelperUtils.getFileAsString("MyMappings.json");
        return Common.mapJsonToObject(jsonResponse, MyMappingResponse.class);
    }
}

The best solution in this case was to fix a JSON file issue, such that the file could be loaded at startup time correctly. MyMappings.json - this file's structure did not match that which was expected by the MyMappingResponse class.

ryanwebjackson
  • 1,017
  • 6
  • 22
  • 36