Search code examples
javaspringspring-bootqualifiers

Error creating bean with controller. Facing issues with autowired and qualifier annotations


I'm creating an application for booking doctors appointments. Here I got 7 classes in pojo class

Inside the package com.capg.bookmydoctor.dto I have 7 pojo classes :

com.capg.bookmydoctor.dto

Admin.java
Appointment.java
Availability.java
Doctor.java
Feedback.java
Patient.java
User.java

Here inside the Dao I got 5 Dao method interfaces and 5 Dao Repository interfaces

com.capg.bookmydoctor.dao


IAdminDao.java

-------------------------------------------------------------------------------------

package com.capg.bookmydoctor.dao;

import com.capg.bookmydoctor.dto.Admin;

public interface IAdminDao {


        public Admin addAdmin(Admin admin);
        public Admin updateAdmin(Admin admin);
        public Admin removeAdmin(Admin admin);
        public Admin viewAdmin(Admin admin);

    }

-------------------------------------------------------------------------------------

IAdminDaoRepository.java

-------------------------------------------------------------------------------------

package com.capg.bookmydoctor.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.capg.bookmydoctor.dto.Admin;

@Repository("IAdminDao")
public interface IAdminRepository extends IAdminDao, JpaRepository<Admin, Integer>{

}

Here I'm embedding only one Dao Interface and one Dao Repository interface code to make question small. Rest of the Interfaces are similar.

IAppointmentDao.java
IAppointmentRepository.java

IDoctorDao.java
IDoctorRepository.java

IFeedbackDao.java
IFeedbackRepository.java

IPatientDao.java
IPatientRepository.java

Here inside the service package I got 5 Service method interfaces and 5 Service Implementation classes

I guess due to these service classes I'm getting error because my main class is unable to find the service class even though I have used @Autowired and @Qualifier annotation.

com.capg.bookmydoctor.service 

IAdminService.java

-------------------------------------------------------------------------------------

package com.capg.bookmydoctor.service;

import com.capg.bookmydoctor.dto.Admin;

public interface IAdminService {


    public Admin addAdmin(Admin admin);
    public Admin updateAdmin(Admin admin);
    public Admin removeAdmin(Admin admin);
    public Admin viewAdmin(Admin admin);

    }

-------------------------------------------------------------------------------------

IAdminServiceImpl.java

-------------------------------------------------------------------------------------

package com.capg.bookmydoctor.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.capg.bookmydoctor.dao.IAdminRepository;
import com.capg.bookmydoctor.dto.Admin;

@Service("IAdminService")
public class IAdminServiceImpl implements  IAdminService {

    @Autowired
    @Qualifier("IAdminRepository")
    IAdminRepository adminDao;

    @Override
    public Admin addAdmin(Admin admin) {
        return adminDao.addAdmin(admin);
    }

    @Override
    public Admin updateAdmin(Admin admin) {
        return adminDao.updateAdmin(admin);
    }

    @Override
    public Admin removeAdmin(Admin admin) {
        return adminDao.removeAdmin(admin);
    }

   @Override
    public Admin viewAdmin(Admin admin) {
        return adminDao.viewAdmin(admin);
    }

    }

Here I'm embedding only one service Implementation class code to make question small. Rest of the service Implementation classes are similar just variables and methods differ.

IAppointmentService.java
IAppointmentServiceImpl.java


IDoctorService.java
IDoctorServiceImpl.java

IFeedbackService.java
IFeedbackServiceImpl.java

IPatientService.java
IPatientServiceImpl.java

Here Inside the controller package I got one class

com.capg.bookmydoctor.controller

BookMyDoctorController.java

package com.capg.bookmydoctor.controller;

import java.time.LocalDate;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.capg.bookmydoctor.dto.Admin;
import com.capg.bookmydoctor.dto.Appointment;
import com.capg.bookmydoctor.dto.AvailabilityDates;
import com.capg.bookmydoctor.dto.Doctor;
import com.capg.bookmydoctor.dto.FeedBack;
import com.capg.bookmydoctor.dto.Patient;
import com.capg.bookmydoctor.service.IAdminService;
import com.capg.bookmydoctor.service.IAppointmentService;
import com.capg.bookmydoctor.service.IDoctorService;
import com.capg.bookmydoctor.service.IFeedbackService;
import com.capg.bookmydoctor.service.IPatientService;

@RestController
@RequestMapping("/doctor")
public class BookMyDoctorController {

    @Autowired
    @Qualifier("IAdminService")
    IAdminService adminService;

    @Autowired
    @Qualifier("IAppointmentService")
    IAppointmentService appointmentService;

    @Autowired
    @Qualifier("IDoctorService")
    IDoctorService doctorService;

    @Autowired
    @Qualifier("IFeedbackService")
    IFeedbackService feedbackService;

    @Autowired
    @Qualifier("IPatientService")
    IPatientService patientService;

    @PostMapping("/admin")
    public Admin addAdmin(@RequestBody Admin admin) {
        return adminService.addAdmin(admin);
    }

    @PutMapping("/admin")
    public Admin updateAdmin(@RequestBody Admin admin) {
        return adminService.updateAdmin(admin);
   }

    @DeleteMapping("/admin")
    public Admin removeAdmin(@RequestBody Admin admin) {
        return adminService.removeAdmin(admin);
    }

    @GetMapping("/admin")
    public Admin viewAdmin(@RequestBody Admin admin) {
        return adminService.viewAdmin(admin);
     }

    @GetMapping("/appointment")
    public List<Appointment> getAllAppointments() {
        return appointmentService.getAllAppointments();
    }

    @GetMapping("/feedback/all")
    public List<FeedBack> getAllFeedback(@RequestBody Doctor doc) {
        return feedbackService.getAllFeedback(doc);
    }

    @PostMapping("/patient")
    public Patient addPatient(@RequestBody Patient bean) {
        return patientService.addPatient(bean);
    }

    @PutMapping("/patient")
    public Patient editPatientProfile(@RequestBody Patient bean) {
        return patientService.editPatientProfile(bean);
    }

    @DeleteMapping("/patient")
    public Patient removePatientDetails(@RequestBody Patient bean) {
        return patientService.removePatientDetails(bean);
    }

    @GetMapping("/patient")
    public Patient getPatient(@RequestBody Patient patient) {
        return patientService.getPatient(patient);
    }

    @GetMapping("/patient/all")
    public List<Patient> getAllPatient() {
        return patientService.getAllPatient();
    }

    @GetMapping("/patient/doctor")
    public List<Patient> getPatientListByDoctor(@RequestBody Doctor doctor) {
        return patientService.getPatientListByDoctor(doctor);
    }

    @GetMapping("/patient/{appdate}")
    public List<Patient> getPatientListByDate(@PathVariable LocalDate appdate) {
        return patientService.getPatientListByDate(appdate);
    }

Here inside the package com.capg.bookmydoctor I got spring booth application class

com.capg.bookmydoctor 

package com.capg.bookmydoctor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.capg.bookmydoctor.controller,com.capg.bookmydoctor.dao,com.capg.bookmydoctor.service,com.capg.bookmydoctor.dto")
public class BookMyDoctorAppApplication {

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

    }

Here I have used same package name "com.capg.bookmydoctor" for all packages.

Here I have used @Service Annotation for all Service Implementation classes and specified service interface name in it.

I have used @Qualifier annotation with @Autowired since I got different Respositories and Service Implementation classes.

Inspite of doing all this I'm getting these errors in console

Errors:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookMyDoctorController': Unsatisfied dependency expressed through field 'adminService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'IAdminService': Unsatisfied dependency expressed through field 'adminDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.capg.bookmydoctor.dao.IAdminRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=IAdminRepository)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.5.jar:5.3.5]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.5.jar:5.3.5]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:769) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313) [spring-boot-2.4.4.jar:2.4.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) [spring-boot-2.4.4.jar:2.4.4]
at com.capg.bookmydoctor.BookMyDoctorAppApplication.main(BookMyDoctorAppApplication.java:12) [classes/:na]

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'IAdminService': Unsatisfied dependency expressed through field 'adminDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.capg.bookmydoctor.dao.IAdminRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=IAdminRepository)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.5.jar:5.3.5]
... 21 common frames omitted

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.capg.bookmydoctor.dao.IAdminRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=IAdminRepository)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.5.jar:5.3.5]
... 35 common frames omitted

Please Help me to get rid of these errors

Thank you...


Solution

  • In the IAdminRepository, the name of the bean is "IAdminDao".

    package com.capg.bookmydoctor.dao;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    import com.capg.bookmydoctor.dto.Admin;
    
    @Repository("IAdminDao")
    public interface IAdminRepository extends IAdminDao, JpaRepository<Admin, Integer>{
    
    }
    

    In the service class IAdminServiceImpl, you're autowiring with wrong Qualifier:

        @Autowired
        @Qualifier("IAdminRepository")
        IAdminRepository adminDao;
    

    It should be:

        @Autowired
        @Qualifier("IAdminDao")
        IAdminRepository adminDao;
    

    You should check for this in other DAO/Service classes.