Why is bean not found during Spring Boot? - java

I reconfigured my DAOs to a more convenient way (by using JpaRepository) instead of doing all that boilerplate code manually. But now everytime I start the Spring Application it gives me the following error:
APPLICATION FAILED TO START
Description:
Field userRepository in DAO.UserDAOService required a bean of type 'DAO.UserRepository' 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 'DAO.UserRepository' in your configuration.
Process finished with exit code 1

SOLUTION: Just create sub-packages in the same package where you have your Spring appliciation located.
EXAMPLE OF SOLUTION CAN BE FOUND HERE: 'Field required a bean of type that could not be found.' error spring restful API using mongodb

You've forgot to put an annotation on your repository class. That's why Spring cannot find that bean.
Try adding #Repository on top of your class definition.

Add #Repository annotation then bean will created and autowired in service.
import org.springframework.stereotype.Repository;
#Repository
public interface UserRepository extends JpaRepository<User , Integer>
{
}
And don't need to create bean in service
#Bean
public void setUserRepository(UserRepository userRepository)
{
this.userRepository = userRepository;
}

Make sure that you have your repository class in a sub-package of the ApplicationConfiguration class.
Annotate the repository class with #Repository.

In addition to the previous answers, the IDE can often suggests you the wrong import for the annotation of the Bean class, for example for a #Service annoted bean, be sure that you import:
import org.springframework.stereotype.Service;
and not something like:
import org.jvnet.hk2.annotations.Service

Related

Consider defining a bean of type 'com.service.AdminService' in your configuration

APPLICATION FAILED TO START
Description:
Field adminService in com.controller.AdminController required a bean of type 'com.service.AdminService' 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.service.AdminService' in your configuration.
Use this snippet of code it will work.
#Controller
public class AdminController{
private AdminService adminService;
#Autowired
public AdminController(AdminService adminService){
this.adminService=adminService;
}
}
And also use #Service annotation above the AdminService Interface.
Update to #ComponentScan(basePackages = {"com.cybage.*"}) in DoctorOnFingerTipsApplication.java class
The line
#ComponentScan(basePackages = {"com.cybage.controller"})
in DoctorOnFingerTipsApplication.java tells to scan components in the package com.cybage.controller directory only.
Since your AdminService is in 'com.cybage.service' package, springboot does not register this as a component.
So change the ComponentScan to scan all packages where you think your components will be present. If you intend to write your components within directories(/services, /respositories, etc. for example) in 'com.cybage' package, update your ComponentScan to :
#ComponentScan(basePackages = {"com.cybage.*"})
where '*' corresponds to all items within the 'com.cybage' package.

How to #Autowire services in SpringBoot

Good day, guys. I have a question about autowiring services into my classes when using Springboot. All of the examples I have seen on the Internet as well as in the Springboot specification do something of the like (taking an excerpt from the Springboot version 1.5.7 specification):
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
#Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
This is a class that injects a property through its constructor, by means of #Autowiring the constructor. Another form is to #Autowire the property like this:
#Autowired
private final RiskAssessor riskAssessor
But, where I work, for these two methods to work, I have been told that I need to use this method:
applicationContext.getAutowireCapableBeanFactory().autowireBean(Object.class)
They have told me that I need this in order for the #Autowired annotation to work.
Now my question to you is: why is there no simple annotation that allows the #Autowire to function correctly? (Something like #AutowiredClass). The above method is too verbose and hard to remember, so surely there must be a better way to make #Autowired work on classes in order to inject services, just like we do in Grails where we just say def someService and it is automatically injected.
If you want properly use #Autowired in your spring-boot application, you must do next steps:
Add #SpringBootApplicationto your main class
Add #Service or #Component annotation to class you want inject
Use one of two ways that you describe in question, to autowire
If you don't have any wiered package structure and the main class package includes all other classes you want spring to instantiate (directly or in the subpackages) a simple annotation #ComponentScan on your main class will help you save all those boiler plate code. Then spring will do the magic, it will go and scan the package(and subpackages) and look for classes annotated with #Service, #Component etc and instantiate it.
Even better, use #SpringBootApplication in your main class, this will cover #Configuration as well. If it is a green field project , I would encourage to start from start.spring.io - a template generation/scaffolding tool for spring
Now my question to you is: why is there no simple annotation that allows the #Autowire to function correctly?
There is: #SpringBootApplication
If you put this at the root of your application (file that contains the main class) and as long as your services are at the same package or a sub-package, Spring will auto-discover, instantiate, and inject the proper classes.
There's an example in this walk-through: REST Service with Spring Boot
As described in that page:
#SpringBootApplication is a convenience annotation that adds all of the following:
#Configuration tags the class as a source of bean definitions for the application context.
#EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.
#ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.
You need to annotate the implementation of RestService as a #Service or #Component so Spring would pick it up.
#Service
public class MyRiskAssessorImpl implements RiskAssessor {
///
}
#Autowired almost works out of the box. Just do your component scanning of the class you want to autowire and you are done. Just make sure your main class (or main configuration class) uses #ComponentScan("{com.example.app}") or #SpringBootApplication (main class). The docs explain this stuff pretty good

How custom Account Repository become a bean without any annotation ?

I customized the spring security for my spring boot app.
I use a custom Account Repository:
import org.springframework.data.jpa.repository.JpaRepository;
import com.boot.cut_costs.config.security.CustomUserDetails;
public interface AccountRepository extends JpaRepository<CustomUserDetails, String>{
public CustomUserDetails findByUsername(String username);
}
As you can see, I don't use any annotation for it. But in other classes, I can access it as a bean ? how is it possible ?
When you are using spring boot and your main application class in a root package above other classes then the bean classes will be scanned and detected automatically and you can look here on this.
The #SpringBootApplication annotation is equivalent to using
#Configuration, #EnableAutoConfiguration and #ComponentScan.
Also, #EnableAutoConfiguration annotation implicitly defines a base
“search package” for certain items.
Check out this annotation #EnableJpaRepositories. You may be using it as a class level annotation on one of your #Configuration class.
From the docs
Annotation to enable JPA repositories. Will scan the package of the annotated configuration class for Spring Data repositories by default.
Example:
#Configuration
#EnableJpaRepositories(basePackages = {"xxx.xxx.xxx.core.dao"})
#EnableTransactionManagement
public class DatabaseConfig{
}

Does annotating a repository interface as #Component have any cons?

I have this interface:
public interface liteRepository extends CrudRepository<liteEntity, Long>, JpaSpecificationExecutor<liteEntity> {...}
It works, all is well.
However, intellij does not register this class as a spring component. If I annotate this interface with #Component, then intellij recognizes this as a spring bean and I can #Autowire this repository in my integration tests.
My code still works after annotation, but I'm not confident that I am not messing with things that I should not be messing with.
Question:
Is there any harm in adding the #Component annotation to this interface?
The only thing that #Component annotation means is that the class is eligible for becoming a Spring bean during Spring's component-scan.
So, if you want it to be a Spring bean and you did not define it as a Spring bean anywhere else, you can safely add the #Component annotation.
Of course, this will only work if you have the actual component scan configured somewhere(for, example <context:component-scan base-package="..."> in some Spring config file), which I am assuming you already heave, since the bean is properly getting autowired after you add the annotation.

Spring #ComponentScan for #Service

I have a package named com.example.service, and in my Spring Configuration class I have the annotation #ComponentScan({"com.example.service"},{"com.example.controller"}).
When I try to #Autowire a service, code compilation fails with a NoSuchBeanDefinitionException. The MyService interface is annotated with #Service.
Currently I use a quite ugly workaround and declare every single service bean in my ExampleConfig.java like
#Bean
public MyService myService() {
return new MyServiceImpl();
}
Generally the #ComponentScan seems to work, if I remove the controller package, the controllers are not found. What did I understand wrong? Please let me know, if I missed out any relevant information.
The MyService interface is annotated with #Service
You must annotate the implementation of your interface. Not the interface itself.
Try using below code for ComponentScan annotation for scanning multiple packages:
#ComponentScan({"com.example.service","com.example.controller"})
instead of
#ComponentScan({"com.example.service"},{"com.example.controller"})
#ComponentScan uses string array for scanning multiple base packages.

Categories