BeanNotOfRequiredTypeException due to autowired fields

106,763

Solution 1

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

use interface AdminService rather than the implements.

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

Solution 3

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

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

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.

Share:
106,763
Valknut
Author by

Valknut

Back in business))

Updated on October 20, 2020

Comments

  • Valknut
    Valknut over 3 years

    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";
        } ....