BeanNotOfRequiredTypeException due to autowired fields

JavaSpring MvcAnnotationsTomcat7

Java Problem Overview


I'm still new to Spring MVC and while building my test project, I got this message from Tomcat logs:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'divisionController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:307)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    ...
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:360)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)

I have two rolle services for user and admin with there interfaces:

package employee.service;

import employee.model.EmployeeDiv;
import employee.model.EmployeeInfo;
import employee.model.UserInfo;

import java.util.List;

/**
 *
 * @author serge
 */

public interface AdminService extends UserService {

     //  !!!! for register & udate of Employee use String type birthday !!!!

    /*
     * Employee
     */
    public EmployeeInfo registerEmployee(EmployeeInfo employeeInfo);

    public EmployeeInfo updateEmployee(EmployeeInfo employeeInfo);
        
    public EmployeeInfo findEmployeeByID(Integer id);   
    
    /*
     * Division
     */
    public EmployeeDiv registerDivision(EmployeeDiv division);

    public EmployeeDiv updateDivision(EmployeeDiv division);
    
    public List<EmployeeDiv> findAllDivisions();

    public List<EmployeeDiv> findDivisionsByName(EmployeeDiv division);
    
    public EmployeeDiv findDivisionsById(Integer id);

    /*
     * Login
     */
    public UserInfo registerUser(UserInfo user);

    public UserInfo updateUser(UserInfo user);
    
    public List<UserInfo> findAllUsesrs();

    public List<UserInfo> findUsesrByLogin(UserInfo user);
    
    public UserInfo findUsesrById(Integer id);
}

This is AdminServiceImpl:

package employee.service.impl;

import employee.DAO.EmployeeDivDAO;
import employee.DAO.EmployeeInfoDAO;
import employee.DAO.UserDAO;
import employee.model.EmployeeDiv;
import employee.model.EmployeeInfo;
import employee.model.UserInfo;
import employee.service.AdminService;
import employee.validation.ParsingDate;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author serge
 *
 * Admin level
 *
 * Service for processing employee, divisions, userslogin
 */

//@Repository("adminService")
@Service("adminService")
@Transactional
public class AdminServiceImpl extends UserServiceImpl implements AdminService {

    protected static Logger adminLogger = Logger.getLogger("service");
    private EmployeeDivDAO emplDivDAO;
    private UserDAO userDAO;
    private EmployeeInfoDAO emplInfoDAO;

    @Autowired
    @Override
    public void setEmployeeDao(EmployeeInfoDAO emplInfoDAO) {
        this.emplInfoDAO = emplInfoDAO;
    }

    @Autowired
    public void setEmployeeDao(EmployeeDivDAO emplDivDAO) {
        this.emplDivDAO = emplDivDAO;
    }

    @Autowired
    public void setUserDao(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public AdminServiceImpl() {

        initTestEmployee();
    }

    /**
     * Initialize EmployeeInfo test
     */
    @Transactional
    @Secured("ROLE_ADMIN")
    private EmployeeInfo initTestEmployee() {

        adminLogger.debug("saving testEmployee");

        EmployeeInfo employeeInfo = new EmployeeInfo();
        ParsingDate date = new ParsingDate();
        employeeInfo.setFirstName("Petr");
        employeeInfo.setLastName("Ivanenko");
        employeeInfo.setEmpDiv("second");
        employeeInfo.setBirthdate(date.parseDate("1981-10-03"));
        employeeInfo.setSalary(3500);
        employeeInfo.setActive(true);

        return employeeInfo;
    }

    /**
     * registrating new Employee Information
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo registerEmployee(EmployeeInfo employeeInfo) {

        adminLogger.debug("registrating new Employee");

        try {
            
            emplInfoDAO.save(employeeInfo);

        } catch (NullPointerException e) {
        }
        return employeeInfo;
    }
    
    /**
     * updating Employee Information
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo updateEmployee(EmployeeInfo employeeInfo) {

        adminLogger.debug("updating Employee with id: " + employeeInfo.getId());
        try {

            emplInfoDAO.update(employeeInfo);

        } catch (NullPointerException e) {
        }
        return employeeInfo;
    }
    
    /**
     * Retrieving Employee Information by id 
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeInfo findEmployeeByID(Integer id) {

        adminLogger.debug("Retrieving Employee with id= " + id);
        EmployeeInfo employeeInfo = new EmployeeInfo();
        employeeInfo.setId(id);
        emplInfoDAO.find(employeeInfo);
        return employeeInfo;
    }
    
    /**
     * registrating new Employee Division
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv registerDivision(EmployeeDiv division) {

        adminLogger.debug("registrating new Division");
        try {

            emplDivDAO.save(division);

        } catch (NullPointerException e) {
        }
        return division;
    }
    
    /**
     * updating Employee Division
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv updateDivision(EmployeeDiv division) {

        adminLogger.debug("updating Division with id: " + division.getId());
        try {

            emplDivDAO.update(division);

        } catch (NullPointerException e) {
        }
        return division;
    }
    
    /**
     * Retrieving all Employee Divisions
     *
     * @return List of EmployeeDiv objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<EmployeeDiv> findAllDivisions() {

        adminLogger.debug("Retrieving all divisions");
        return emplDivDAO.findAll();
    }
    
    /**
     * Retrieving all Employee Divisions by name
     *
     * @return List of EmployeeDiv objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<EmployeeDiv> findDivisionsByName(EmployeeDiv division) {
        String empDiv = "empDiv";

        adminLogger.debug("Retrieving Divisions by name: " + division.getEmpDiv());
        return emplDivDAO.findAllByParam(empDiv, division.getEmpDiv());
    }
    
     /**
     * Retrieving Employee Divisions by id 
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public EmployeeDiv findDivisionsById(Integer id) {
        
        adminLogger.debug("Retrieving Division with id= " + id);
        EmployeeDiv employeeDiv = new EmployeeDiv();
        employeeDiv.setId(id);
        emplInfoDAO.find(employeeDiv);
        return employeeDiv;
    }
    
    /**
     * registrating new User Information
     *
     * @return UserInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo registerUser(UserInfo user) {

        adminLogger.debug("registrating new User");
        try {

            userDAO.save(user);

        } catch (NullPointerException e) {
        }
        return user;
    }
    
    /**
     * updating new User Information
     *
     * @return UserInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo updateUser(UserInfo user) {

        adminLogger.debug("updating User with id: " + user.getId());
        try {

            userDAO.update(user);

        } catch (NullPointerException e) {
        }
        return user;
    }
    
    /**
     * retriviting all Users 
     *
     * @return List of UserInfo objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<UserInfo> findAllUsesrs() {

        adminLogger.debug("Retrieving all Users");
        return userDAO.findAll();
    }
    
    /**
     * retriving all Users by login
     *
     * @return List of UserInfo objects
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public List<UserInfo> findUsesrByLogin(UserInfo user) {
        String login = "login";

        adminLogger.debug("Retrieving User with login: " + login);
        return userDAO.findAllByParam(login, user.getLogin());
    }
    
    /**
     * Retrieving Employee Divisions by id 
     *
     * @return EmployeeDiv object
     */
    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public UserInfo findUsesrById(Integer id) {
        
        adminLogger.debug("Retrieving Division with id= " + id);
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        emplInfoDAO.find(userInfo);
        return userInfo;
    }
}

This is applicationContext.xml

<?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: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-3.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
	
    <!-- Activates annotations -->

    <context:annotation-config />
	
    <!-- Scans for annotated components in base-package-->

    <context:component-scan base-package="employee" />

    <bean class="employee.service.impl.AdminServiceImpl"/>
    <bean class="employee.service.impl.UserServiceImpl"/>
    <!--bean class="employee.DAO.impl.EmployeeInfoDAOImpl"/>
    <bean class="employee.DAO.impl.EmployeeDivDAOImpl"/>
    <bean class="employee.DAO.impl.UserDAOImpl"/-->

    <!-- for Spring Jackson JSON support  -->

    <mvc:annotation-driven/>

    <!-- Shared Hibernate SessionFactory in a Spring application context. -->

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>

        <!--property name="dataSource">
            <ref bean="dataSource"/>
        </property-->

        <property name="annotatedClasses">
            <list>
                <value>employee.model.UserInfo</value>
                <value>employee.model.EmployeeInfo</value>
                <value>employee.model.EmployeeDiv</value>
            </list>
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- for database, imports the properties from database.properties -->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:database.properties"/>
    </bean>
</beans>

Please tell me what is the problem with this bean name, I understand that is AOP problem:

Bean named 'adminService' must be of type [employee.service.impl.AdminServiceImpl], but was actually of type [$Proxy52]

how I can fix it?

I use AdminServiceImpl in Controllers:

package employee.controller;

import employee.model.EmployeeDiv;
import employee.service.impl.AdminServiceImpl;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;

/**
 * @author serge
 *
 * Handles and retrieves division related requests
 */
@Controller
@RequestMapping("/division")
public class DivisionController {
    
    protected static Logger logger = Logger.getLogger("controller");
    @Resource(name = "adminService")
    private AdminServiceImpl adminService;

    /**
     * Handles and retrieves a /WEB-INF/jsp/divisionpage.jsp
     *
     * containing all division
     *
     * @return the name of the JSP page
     */
    @RequestMapping(method = RequestMethod.GET)
    public String getAllPage(Model model) {
        logger.debug("Received request to show all division page");

        // Retrieve all division and attach to model 
        model.addAttribute("division", adminService.findAllDivisions());
        return "divisionpage";
    } ....

Java Solutions


Solution 1 - Java

Somewhere in your code you must be autowiring AdminServiceImpl like this:

@Autowired
private AdminServiceImpl adminService;

Either depend barely on interface:

@Autowired
private AdminService adminService;

or enabled CGLIB proxies.

Similar problems

Solution 2 - Java

use interface AdminService rather than the implements.

this error caused by Annotation @Transactional, Spring makes a proxy for AdminService at Runtime.

Solution 3 - Java

When your service class implements some interface, spring by default takes proxy by JDK, that's why you get that error, so you can solve that problem whether using @Autowired over the interface or enabling the CGLIB proxy.

I solved that problem enabling CGLIB proxy using proxy-target-class attribute in my spring application context

<tx:annotation-driven proxy-target-class="true"
		transaction-manager="transactionManager" />

Solution 4 - Java

I found lots of questions similar to this one, when searching google for my problem. However, in my case I already used an interface. So I thought this might be helpful for others:

This exception could also appear, if you have two beans with the same name!

In my case I had additional bean configuration in my applicationContext.xml. The problem appeared after I merged two applications. The second one defined a @Resource and its member-variable name matched the bean name of the first application, mentioned above. Of course, the bean configuration of the first application didn't fit for the bean included via @Resource by the second application.

Solution 5 - Java

I have facing same issue but I solved the problem with the following workaround:

Please replace your implementation class with interface. For example:

class Abc
{
 @Autowire
 private Boy boy // remove @BoyImpl

.............
...................
}

Solution 6 - Java

I also had this problem with some @SpringBootTest classes that were testing endpoints. The endpoints had a dependency on a DB Service that has @Transactional on a few methods.

Because of the @Transactional, Spring intercepts that and creates a proxy class, so Spock (or junit) would struggle to inject the correct mock.

My workaround was to push the DB Service down one layer and have plain Spock tests around the middle layer which aren't affected by this.

Solution 7 - Java

Make sure you have enabled proxyTargetClass on, like:

@EnableTransactionManagement(proxyTargetClass = true)

Solution 8 - Java

I also have met the problem when execute unit test

I created a mock service to implement the real service to override some method for easy to test some user case

@Component
public static class FooServiceImplMock extends FooServiceImpl {
    @Override
    protected void bar() {
        // do some specific loginc here 
    }
}

but when execute the test method

@Autowired
private Foo1ServiceImplMock foo1ServiceImplMock;

I got below error

Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooServiceImplTest.FooServiceImplMock' is expected to be of type 'com.foo.business.impl.FooServiceImplTest$FooServiceImplMock' but was actually of type 'com.sun.proxy.$Proxy97'

Reason:

There is method in FooServiceImpl used @Cacheable

@Cacheable("eventTypes")

And from javadoc of EnableCaching I know

org.springframework.cache.annotation.EnableCaching 
boolean proxyTargetClass()

Indicate whether subclass-based (CGLIB) proxies are to be created as opposed to standard Java interface-based proxies. The default is false.

So the resolve manner is explicitly to specify use CGLIB in spring application contenxt

 <cache:annotation-driven proxy-target-class="true"/>

Solution 9 - Java

I just experienced this issue when a test on an existing class started failing with 'expected to be of type...but was actually of type 'com.sun.proxy.$Proxy115'.

What it turned out to be was that I had used Intellij's 'pull method up [to interface]' on an @Transactional method that I had added to the interface's implementation class, and Intellij decided to add @Transactional to the interface method declaration. If there is just one @Transactional method in an interface then it seems to screw things up, resulting in this error.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionValknutView Question on Stackoverflow
Solution 1 - JavaTomasz NurkiewiczView Answer on Stackoverflow
Solution 2 - JavaBobJiangView Answer on Stackoverflow
Solution 3 - JavaChristian Altamirano AyalaView Answer on Stackoverflow
Solution 4 - JavafishboneView Answer on Stackoverflow
Solution 5 - JavapankajView Answer on Stackoverflow
Solution 6 - JavaJimmyView Answer on Stackoverflow
Solution 7 - JavaKhairul Bashar LemonView Answer on Stackoverflow
Solution 8 - JavazhuguoweiView Answer on Stackoverflow
Solution 9 - JavaJL_SOView Answer on Stackoverflow