How To Resolve 'org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean ....' Using @Qualifier Annotation?

Hello everyone, in this article we will learn how to resolve
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.demo.components.Human' available: expected single matching bean but found 2: employee,employer
using @Qualifier Annotation or using @Primary Annotation.



Before going to the example just a quick overview of NoUniqueBeanDefinitionException and @Qualifier Annotation.

NoUniqueBeanDefinitionException:


The 'org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type available: expected single matching bean but found' will be thrown when the bean is auto-wired that matches two or more loaded beans in the spring boot application context. As a result, the bean could not be auto-wired. 
The ApplicationContext represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the aforementioned beans.


@Qualifier Annotation:


The @Qualifier annotation is utilized to resolve the autowiring conflict when there are multiple beans of the same type.  If we have more than one bean of the same type and optate to wire only one of them then utilize the @Qualifier annotation along with @Autowired to specify which exact bean will be wired.


@Primary Annotation:


@Primary is used to give high preference to the specific bean among multiple beans of the same type to inject into a bean.

Reproduce the issue using the following example,

Human interface:

public interface Human {

public void eat();

}

Employee Bean:

import org.springframework.stereotype.Component;

@Component
public class Employee implements Human {

@Override
public void eat() {
System.out.println("Employee eating");

}
}

Employer Bean:

import org.springframework.stereotype.Component;

@Component
public class Employer implements Human {

@Override
public void eat() {
System.out.println("Employer eating");

}
}

Human Service:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.components.Human;

@Service
public class HumanService {

@Autowired
private Human human;

public void service() {
human.eat();
}
}

Spring Boot Main Driver:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.example.demo.service.HumanService;

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

@Autowired
private HumanService humanService;

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

@Override
public void run(String... args) throws Exception {
humanService.service();

}
}

Exception:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'demoApplication': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'humanService': Unsatisfied dependency expressed through field 'human'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.demo.components.Human' available: expected single matching bean but found 2: employee,employerError starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-04-24 15:18:08.937 ERROR 13313 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

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

Description:

Field human in com.example.demo.service.HumanService required a single bean, but 2 were found:
        - employee: defined in file [/home/user/Downloads/spring-quartz-joblistener-demo/target/classes/com/example/demo/components/Employee.class]
        - employer: defined in file [/home/user/Downloads/spring-quartz-joblistener-demo/target/classes/com/example/demo/components/Employer.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed



Solutions


Solution 1: Using @Qualifier Annotation

Injecting Employee bean in HumanService using @Autowired with @Qualifier annotation.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.example.demo.components.Human;

@Service
public class HumanService {

@Autowired
@Qualifier("employee")
private Human human;

public void service() {
human.eat();
}
}


Console Output:

Employee eating



Solution 2: Using @Primary Annotation

In the below Employee class, we have added @Primary with @Component annotation. @Primary is used to give high preference to the specific bean among multiple beans of the same type to inject into a bean.
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class Employee implements Human {

@Override
public void eat() {
System.out.println("Employee eating");

}
}


Console Output:

Employee eating


More ...

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete