2017-05-08 104 views
2

我嘗試使用Spring MVC和Hibernate運行我的第一個Web應用程序,但我遇到了一些問題。UnsatisfiedDependencyException:創建bean時出錯(通過BeanNotOfRequiredTypeException)

GenericDao:

@Repository 
public abstract class GenericDao<T> implements GeneralDao<T> { 

    private Class<T> className; 

    protected GenericDao(Class<T> className) { 
     this.className = className; 
    } 

    @PersistenceContext 
    private EntityManager entityManager; 

    public EntityManager getEntityManager() { 
     return entityManager; 
    } 

    @Override 
    public void add(T object) { 
     try { 
      getEntityManager().persist(object); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_ADD_ENTITY_FAIL, e); 
     } 
    } 

    @Override 
    public void update(T object) { 
     try { 
      getEntityManager().merge(object); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_UPDATE_ENTITY_FAIL, e); 
     } 
    } 

    @Override 
    public void remove(T object) { 
     try { 
      getEntityManager().remove(object); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_REMOVE_ENTITY_FAIL, e); 
     } 
    } 

    @Override 
    public T getById(int id) { 
     try { 
      return getEntityManager().find(this.className, id); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_GET_BY_ID_ENTITY_FAIL, e); 
     } 
    } 

    public abstract List<T> getAll() throws DaoException; 

} 

UserDao.java:

@Repository 
public class UserDao extends GenericDao<User> { 
    private final static String USER_LOGIN = "login"; 
    private final static String USER_PASSWORD = "password"; 

    private UserDao() { 
     super(User.class); 
    } 

    @Override 
    public List<User> getAll() { 
     List<User> userList; 
     try { 
      userList = getEntityManager().createQuery(Statement.GET_ALL_USERS).getResultList(); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_GET_ALL_ENTITY_FAIL, e); 
     } 
     return userList; 
    } 

    public List<User> getByLoginAndPassword(String userLogin, String userPassword) { 
     CriteriaQuery<User> criteriaQuery; 
     try { 
      CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder(); 
      criteriaQuery = criteriaBuilder.createQuery(User.class); 
      Root<User> userRoot = criteriaQuery.from(User.class); 
      criteriaQuery.select(userRoot); 
      criteriaQuery.where(
        criteriaBuilder.equal(userRoot.get(USER_LOGIN), userLogin), 
        criteriaBuilder.equal(userRoot.get(USER_PASSWORD), userPassword) 
      ); 
     } catch (HibernateException e) { 
      throw new DaoException(ErrorMessage.MESSAGE_GET_ENTITY_BY_LOGIN_AND_PASSWORD_FAIL, e); 
     } 
     return getEntityManager().createQuery(criteriaQuery).getResultList(); 
    } 
} 

GenericService.java:

@Service 
public abstract class GenericService<T> implements GeneralService<T> { 

    private static Logger logger = Logger.getLogger(GenericService.class); 

    @Autowired 
    private GenericDao<T> dao; 

    @Transactional 
    @Override 
    public void add(T object) throws ServiceException { 
     try { 
      dao.add(object); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
    } 

    @Transactional 
    @Override 
    public void update(T object) throws ServiceException { 
     try { 
      dao.update(object); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
    } 

    @Transactional 
    @Override 
    public void remove(T object) throws ServiceException { 
     try { 
      dao.remove(object); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
    } 

    @Transactional(readOnly = true) 
    @Override 
    public T getById(int id) throws ServiceException { 
     try { 
      return dao.getById(id); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
    } 

    @Transactional(readOnly = true) 
    @Override 
    public List<T> getAll() throws ServiceException { 
     try { 
      return dao.getAll(); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
    } 

} 

UserService.java:

@Service 
public class UserService extends GenericService<User> { 

    private static Logger logger = Logger.getLogger(UserService.class); 

    @Autowired 
    private UserDao userDao; 

    @Transactional 
    public String checkUser(String userLogin, String userPassword) throws ServiceException { 
     String namePage = "errorAuthorization"; 
     List<User> userList; 
     try { 
      userList = userDao.getByLoginAndPassword(userLogin, userPassword); 
     } catch (DaoException e) { 
      logger.debug(e); 
      throw new ServiceException(e.getMessage()); 
     } 
     if(userList.size() != 0) { 
      return UserRoleChecker.defineUserPage(userList.get(0)); 
     } 
     return namePage; 
    } 

    public void addUser(String userLogin, String userPassword, String userMail) throws ServiceException{ 
     Role role = new Role(0, RoleType.USER); 
     User user = new User(0, userLogin, userPassword, userMail, role); 
     add(user); 
    } 

} 

UserController.java:

@Controller 
public class UserController { 
    private static String className = UserController.class.getName(); 

    @Autowired 
    private UserService userService; 

    @RequestMapping(value = "/check_user", method = RequestMethod.POST) 
    public ModelAndView authorizationUser(HttpServletRequest request, HttpServletResponse response) { 
     ModelAndView modelAndView = new ModelAndView(); 
     String returnPage; 
     try { 
      returnPage = userService.checkUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD)); 
     } catch (ServiceException e) { 
      returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); 
     } 
     modelAndView.setViewName(returnPage); 
     return modelAndView; 
    } 

    @RequestMapping(value = "/add_user", method = RequestMethod.POST) 
    public ModelAndView registrationUser(HttpServletRequest request, HttpServletResponse response) { 
     ModelAndView modelAndView = new ModelAndView(); 
     String returnPage = Page.SUCCESSFUL_REGISTRATION; 
     try { 
      userService.addUser(request.getParameter(RequestParameter.USER_LOGIN), request.getParameter(RequestParameter.USER_PASSWORD), request.getParameter(RequestParameter.USER_MAIL)); 
     } catch (ServiceException e) { 
      returnPage = ErrorHandler.returnErrorPage(e.getMessage(), className); 
     } 
     modelAndView.setViewName(returnPage); 
     return modelAndView; 
    } 

} 

根context.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:p="http://www.springframework.org/schema/p" 
     xmlns:c="http://www.springframework.org/schema/c" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:util="http://www.springframework.org/schema/util" 
     xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd 
     http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <context:annotation-config /> 

    <context:component-scan base-package="by.netcracker.artemyev" /> 

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> 
     <property name="url" value="jdbc:mysql://localhost:3306/airline?useSSL=false" /> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
     <property name="username" value="root"/> 
     <property name="password" value="root"/> 
     <property name="initialSize" value="5"/> 
     <property name="maxTotal" value="10"/> 
    </bean> 

    <bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="by.netcracker.artemyev" /> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="true" /> 
       <property name="database" value="MYSQL" /> 
       <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> 
      </bean> 
     </property> 
     <property name="jpaProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="debug">true</prop> 
       <prop key="connection.isolation">2</prop> 
       <prop key="hibernate.cglib.use_reflection_optimizer">true</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
      </props> 
     </property> 
     <property name="jpaDialect" ref="jpaDialect" /> 
    </bean> 

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManager" /> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jpaDialect" ref="jpaDialect" /> 
    </bean> 

</beans> 

日誌:

org.springframework.web.context.ContextLoader 2017-05-09 11:48:21,198 ERROR - Context initialization failed 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'userService' is expected to be of type 'by.netcracker.artemyev.service.UserService' but was actually of type 'com.sun.proxy.$Proxy31' 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:443) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:325) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4744) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5206) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) 
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1702) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:456) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:405) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) 
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) 
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) 
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) 
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324) 
    at sun.rmi.transport.Transport$1.run(Transport.java:200) 
    at sun.rmi.transport.Transport$1.run(Transport.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'userService' is expected to be of type 'by.netcracker.artemyev.service.UserService' but was actually of type 'com.sun.proxy.$Proxy31' 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1503) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1482) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) 
    ... 60 more 

問題:請解釋一下我爲什麼我有這樣的問題,如何解決這個錯誤?

+1

從'UserDao'中刪除'@ Transactional'。您的服務實施負責交易管理,而不是您的DAO。 ---另外,從'UserDao'構造函數中刪除'@ Autowired',因爲你沒有自動裝配任何東西。 – Andreas

+0

@Andreas,問題未解決 – studentST

回答

2

此問題的原始問題是通過從UserDao中刪除@Transactional來解決的,這需要完成,因爲Service實現負責事務管理,而不是DAO。

還建議從UserDao構造函數中刪除@Autowired,因爲構造函數沒有參數,即它不自動裝配任何東西。

既然這個問題已經修復,那麼代碼與UserControlleruserService字段有類似的問題。

由於Spring使用的是代理模式,因此UserController需要接口UserService實現,而不是類本身。

通常的做法是將類重命名爲UserServiceImpl,然後添加一個名爲UserService的接口。繼續將類UserController的字段userService設爲UserService類型。

+0

非常感謝。詳細的解釋是非常好的答案 – studentST

相關問題