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";
} ....
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.
use interface AdminService
rather than the implements.
this error caused by Annotation @Transactional
, Spring
makes a proxy for AdminService
at Runtime
.
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" />
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.
Make sure you have enabled proxyTargetClass on, like:
@EnableTransactionManagement(proxyTargetClass = true)
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
.............
...................
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With