Spring Injection of resource fields failed - java

I have a BaseDAO and some subClass eg:UserDaoImpl,OrderDaoImpl,now in a BaseService
public abstract class Baservice{
#Resource
private BaseDao basedao;
//something crud operate.....
}
#Service
public UserService extends BaseService{
//....
}
how to configure Spring that I can pass a real subclass to basedao
I encount a exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of resource fields failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.cloudking.trafficmonitor.BaseDAO] is defined: expected single matching bean but found 3: [roleDAO, userDAO

It seems you have 3 classes which extends BaseDAO so all of them are BaseDao (IS A)
You need to use name attribute of #Resource
For example:
#Component
public RoleDao extends BaseDao{/* some code*/}
and
#Component
public UserDao extends BaseDao{/* some code*/}
now if you want to inject UserDao then
#Resource(name="userDao")
BaseDao baseDao

Use #Qualifier("UserDaoImpl")
or use #Resource(name="UserDaoImpl")

Your application is unable to find the bean BaseDAO. You need to annotate BaseDAO with
#Component (or # Service, not sure about this one)

Related

NoUniqueBeanDefinitionException thrown though there is only one implementation

I have a MyService class which has repository field supposed to be injected.
public class MyService {
#Autowired
private MyRepository repository;
// ...ommited
}
And there is MyRepository interface only implemented by MyRepositoryImpl class with #Mapper annotation of MyBatis.
public interface MyRepository {
// ...ommited
}
#Mapper
public interface MyRepositoryImpl extends MyRepository {
// ...ommited
}
When I try to start SpringBootApplication, NoUniqueBeanDefinitionException is thrown.
#SpringBootApplication(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
#MapperScan(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
(...omitted)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'com.example.MyService':
Unsatisfied dependency expressed through field 'repository';
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.example.MyRepository' available:
expected single matching bean but found 2: com.example.MyRepositoryImpl,com.example.MyRepository
(...omitted)
Why is MyRepository interface registered as one of bean even though it doesn't have #Component annotation nor isn't included any bean configurations?
And I found that everything work fine if I don't use FullyQualifiedAnnotationBeanNameGenerator as nameGenerator.
Any ideas?
There can be many other ways to mark an interface as a bean. Some of them are:
#RepositoryDefinition above MyRepository interface
MyRepository extends CrudRepository or JpaRepository
Check if any of these exist.
Update 1:-
The problem seems to be in #MapperScan. What it does is scans for all the interfaces in a package and register them as bean; and if I am not wrong MyRepository and MyRepositoryImpl are in the same package. That's the reason why 2 beans are being created with names com.example.MyRepositoryImpl, com.example.MyRepository and basically both are of same type as MyRepositoryImpl extends MyRepository.
Now when you are using #Autowired on repository field of MyService, it gets confused as in which one to inject. To resolve this the easiest approach is to use #Primary over MyRepositoy which will give that interface a priority while injecting. Another approach is to use #Qualifier("uniqueName") over both the interfaces and also above repository field of MyService along with #Autowired specifying which one you want to inject. You can visit official documentation from here to learn more.Hope this helps a bit .
Spring is not able to figure out the bean whose class is supposed to be implementing the Repository interface.
Put the annotation #Repository above the RepositoryImpl Class. It will find it.

NoUniqueBeanDefinitionException: Don't Control Bean Creation Class

In Spring, is it possible to avoid a NoUniqueBeanDefinitionException in the following scenario:
My application references beans in a 3rd party library
appBean="thirdPartyClass"
The bean code is in a 3rd party library I can't edit
#Component
public class ThirdPartyClass {
#Autowired
private ThirdPartyInterface thirdPartyInterface;
The third party interface is used by two classes I do control
This class:
public class MyClass1 implements ThirdPartyInterface {
and this class:
public class MyClass2 implements ThirdPartyInterface {
Currently, NoUniqueBeanDefinitionException is occurring when I try to start my application saying the following:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'thirdPartyClass': Unsatisfied dependency expressed through field 'thirdPartyIntereface'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'ThirdPartyInterface' available: expected single matching bean but found 2: MyClass1,MyClass2
Considering you cannot change the ThirdPartyClass class.
Make one of the implemented classes as #Primary to be considered as the primary bean to be Autowired in the ThirdPartyClass class.
#Primary
#Component
public class MyClass1 implements ThirdPartyInterface {
}
And add #Qualifier to the other implemented class. And use that same qualifier in your other classes to Autowire and use it seamlessly.
#Component
#Qualifier("queue2")
public class MyClass2 implements ThirdPartyInterface {
}
#Component
public class MyOtherClass {
#Autowired
#Qualifier("queue2")
private ThirdPartyInterface thirdPartyInterface;
}
The error clearly says what the problem is -
When you have 2 class implementing same interface and you are trying to use #Autowired via the interface, Spring does not know which implementation to pick (MyClass1 or MyClass2).
You need to be specific. Use #Qualifier to specify which implementation to pick.
I quickly found one example here - Spring #Autowired and #Qualifier

PermissionEvaluator custom implementation autowiring in one service class but not in other

I have defined a custom PermissionEvaluator :-
public class AppPermissionEvaluator implements PermissionEvaluator {
...
}
In the config class I register this bean :-
/**
* Registers custom Permission evaluator.
*/
#Bean
public PermissionEvaluator permissionEvaluator() {
return new AppPermissionEvaluator();
}
I have two #service classes where I'm trying to autowire this class.
#Autowired
private AppPermissionEvaluator permissionEvaluator;
If I directly autowire the class, it works in one service class but in the other service class it throws an exception NoSuchBeanDefinitionException: No qualifying bean ...
Autowiring the interface works in both service class. I would really like to is it wrong to autowire the class directly and how is it working in one service class but not in other?

What is the bean ID of spring bean implements an interface

When the bean is createt for a class as MyBean the bean id is myBean but what will be the bean ID if I create the service bean from an interface like below?
#Service
public class ProfileServiceImpl implements ProfileService
When I try to access the bean as #profileService thymeleaf gives the below error.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'profileService' is defined
All this time I'm using this bean by autowiring to the controller. But at the moment I need to access this from the thymeleaf.
My thymeleaf code segment
<div th:unless="${#profileService.isMe(user)}">
When Spring creates a Bean Definition from a #Service or #Component annotation, it will by default create an id for the bean by lowercasing the first letter of the Class Name. If you want to override that the behavior, you can provide an alternative id in the annotation, eg. #Service("profileService").
Regarding what you are experiencing with the Repository - by default Spring looks for a custom implementation of a Repository by appending "Impl" to the Repository Interface name. If it finds it, it will not create a default implementation. So, if you had UserRepositoryImpl extends UserRepository instead of UserRepositoryImpl extends DatatablesCriteriasRepository than Spring wouldn't have created the userRepository bean. Addtionally, if you add #NoRepositoryBean annotation to the UserRepository interface, that will suppress the creation of the userRepository bean.
However, UserRepositoryImpl really should be implementing UserRepository. If it really is intended to extend DatatablesCriteriasRepository, than it should be nameed DatatablesCriteriasRepositoryImpl. Having UserRepsitoryImpl extend DatatablesCriteriasRepository is indication of a problem in the design.
for (String name : context.getBeanDefinitionNames()){
System.out.println(name);
}
This test revealed some interesting outcomes.
service beans
Service beans are named after the concrete class name regardless of the interface.
#Service
public class ProfileServiceImpl implements ProfileService
ie. profileServiceImpl in the above question.
Repository beans
Further Repository beans are something more interesting. Below is my crud repository interface without any annotations.
public interface UserRepository extends CrudRepository<User, Long>, DatatablesCriteriasRepository<User>{
And I created an implementation of the UserRepositoryImpl for the DatatablesCriteriasRepository as below without any annotations.
public class UserRepositoryImpl implements DatatablesCriteriasRepository<User>
these two included two beans with IDs userRepository userRepositoryImpl respectively.

Cannot find bean definition , should I annotate an interface too?

I have an interface as show below
public interface UserManager {
void insertUser(User user);
.......
Now I have an implementation class as below
#Service
public class UserManagerImpl implements UserManager {
#Autowired
private UserDAO userDAO;
In my controller
#Controller
public class ExampleGizmoController {
#Autowired
private UserManager userManager;
UserDAOImpl is
#Service
public class UserDAOImpl implements UserDAO {
#Autowired
private SessionFactory sessionFactory;
My application-context.xml
<context:annotation-config/>
<context:component-scan base-package="com.foo" />
which scans all my packages.I have deployed it as war file and when the deployment happens,
The userManager property is not getting autowired to the ExampleGizmoController and shows the error in tomcat as below
Spring-MVC threw load() exception: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [com.foo.UserManager] found for dependency: expected at least 1 bean
which qualifies as autowire candidate for this dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I was able to make out that autowiring was not happening , even though it was annotation driven and component scanning is turned on. Is there anything else I should do for autowiring to work ?
<mvc:annotation-driven/>
is also required in your config file
Maybe it's stupid... but try to remove implements UserManager from UserManager Impl ..
You should use #Service("userManager"). Its a way of telling Spring that you want to name your UserManagerImpl bean instance with "userManager".
Same error i faced, but i've got one more dao class which retrieves information of user manager. You should add #Repository annotation to dao class.
Your another dao class looks like that;
#Repository("userManagerDao")
public class UserManagerDAOImpl implements UserManagerDao{
public UserManagerDTO createNewUserManager() {
UserManagerDTO userManager = new UserManagerDTO();
userManager.setId(1);
userManager.setFirstName("First Name");
userManager.setLastName("Last Name");
return userManager;
}
}

Categories