19

Currently I'm facing an issue in Autowire configuration between controller and the service layer.

I'm unable to trace my mistakes.

Simple Log Info

    SEVERE:   Exception while loading the app
    SEVERE:   Undeployment failed for context /OTT
    SEVERE:   Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.ott.service.EmployeeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

Below I have also given the Controller and Service Layer code and also the dispatcher-servlet.xml

Controller

package com.ott.controller;

import com.ott.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

    /**
     *
     * @author SPAR
     */
    @Controller
    public class AdminController {

        private EmployeeService employeeService;

        @RequestMapping("/employee")
        public String employee(){
            this.employeeService.fetchAll();
            return "employee";
        }

        @Autowired(required = true)
        @Qualifier(value="employeeService")
        public void setEmployeeService(EmployeeService empService) {
            this.employeeService = empService;
        }

    }

Service Interface

package com.ott.service;

import com.ott.hibernate.Employee;
import java.util.List;

/**
 *
 * @author SPAR
 */
public interface EmployeeService {

     List<Employee> fetchAll();


}

Service Interface Impl

package com.ott.service;

import com.ott.dao.EmployeeDAO;
import com.ott.hibernate.Employee;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author SPAR
 */
@Service
public class EmployeeServiceImpl implements EmployeeService{

    private EmployeeDAO employeeDAO;

    @Override
    @Transactional(readOnly = true)
    public List<Employee> fetchAll() {

        List<Employee> employees = employeeDAO.fetchAll();
        for (Employee employee : employees) {

            System.out.println("Name : "+employee.getFirst_Name() +" "+ employee.getLast_Name());

            System.out.println("Email Id : "+employee.getEmail_Id());
        }

        return employees;
    }

    @Autowired(required = true)
    @Qualifier(value="employeeDAO")
    public void setEmployeeDAO(EmployeeDAO empDAO) {
        this.employeeDAO = empDAO;
    }
}

Dispatcher-servlet.xml

 <?xml version='1.0' encoding='UTF-8' ?>
    <!-- was: <?xml version="1.0" encoding="UTF-8"?> -->
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"       
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

        <context:component-scan base-package="com.ott.controller"/>
        <context:component-scan base-package="com.ott.hibernate"/>
        <context:component-scan base-package="com.ott.service"/>
        <context:component-scan base-package="com.ott.dao"/>

        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

        <mvc:resources mapping="/resources/**" location="/resources/" />

         <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
            <property name="definitions">
                <list>
                    <value>/WEB-INF/tiles-def/general-layout.xml</value>
                </list>
            </property>
        </bean>

        <bean id="viewResolverTiles" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView"/>
        </bean> 

        <mvc:annotation-driven />

        <bean
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="prefix">
            <value>/WEB-INF/pages/</value>
          </property>
          <property name="suffix">
            <value>.jsp</value>
          </property>
        </bean>
    </beans>
abhi
  • 1,760
  • 1
  • 24
  • 40
Arun
  • 1,010
  • 6
  • 18
  • 37

9 Answers9

11

Guys I found the issue

I just tried by adding the qualifier name in employee service finally it solved my issue.

@Service("employeeService")

public class EmployeeServiceImpl implements EmployeeService{

}
Arun
  • 1,010
  • 6
  • 18
  • 37
9

I believe for @Service you have to add qualifier name like below :

@Service("employeeService") should solve your issue

or after @Service you should add @Qualifier annontion like below :

@Service
@Qualifier("employeeService")
Ramesh Kotha
  • 8,266
  • 17
  • 66
  • 90
  • Thanks Ramesh just read this documentation at spring http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#beans-scanning-autodetection and finally solved the issue – Arun Feb 16 '15 at 18:17
  • Ramesh @Service need not always have a name and Qualifier. Read my answer for clarity. I don't want your answer to misguide. – minion Feb 16 '15 at 19:25
  • What do you mean by OP? – minion Feb 17 '15 at 14:55
  • i mean as per @Arun, http://meta.stackexchange.com/questions/146513/what-does-op-mean – Ramesh Kotha Feb 17 '15 at 15:01
  • Ramesh, It worked fine after I provided the serviceName to @service, thanks! – Suresh Aug 11 '18 at 15:04
9

You don't have to necessarily provide name and Qualifier. If you set a name, that's the name with which the bean is registered in the context. If you don't provide a name for your service it will be registered as uncapitalized non-qualified class name based on BeanNameGenerator. So in your case the Implementation will be registered as employeeServiceImpl. So if you try to autowire with that name, it should resolve directly.

private EmployeeService employeeServiceImpl;

@RequestMapping("/employee")
public String employee() {
    this.employeeService.fetchAll();
    return "employee";
}

@Autowired(required = true)
public void setEmployeeService(EmployeeService employeeServiceImpl) {
    this.employeeServiceImpl = employeeServiceImpl;
}

@Qualifier is used in case if there are more than one bean exists of same type and you want to autowire different implementation beans for various purposes.

minion
  • 4,313
  • 2
  • 20
  • 35
1

In your controller class, just add @ComponentScan("package") annotation. In my case the package name is com.shoppingcart.So i wrote the code as @ComponentScan("com.shoppingcart") and it worked for me.

1

You forgot @Service annotation in your service class.

Resul Rzaeeff
  • 448
  • 4
  • 14
  • 30
1

@Service: It tells that particular class is a Service to the client. Service class contains mainly business Logic. If you have more Service classes in a package than provide @Qualifier otherwise it should not require @Qualifier.

Case 1:

@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
}

Case2:

@Service
public class EmployeeServiceImpl implements EmployeeService{
}

both cases are working...

Narayan Yerrabachu
  • 1,714
  • 1
  • 19
  • 31
0

If you only have one bean of type EmployeeService, and the interface EmployeeService does not have other implementations, you can simply put "@Service" before the EmployeeServiceImpl and "@Autowire" before the setter method. Otherwise, you should name the special bean like @Service("myspecial") and put "@autowire @Qualifier("myspecial") before the setter method.

Mariuszy
  • 401
  • 4
  • 4
0

Just add below annotation with qualifier name of service in service Implementation class:

@Service("employeeService")
@Transactional
public class EmployeeServiceImpl implements EmployeeService{
}
Amit Kumar
  • 19
  • 2
-1

Missing the 'implements' keyword in the impl classes might also be the issue