UnsatisfiedDependencyException:创建bean时出错(通过BeanNotOfRequiredTypeException)

时间:2017-05-08 22:49:46

标签: java spring spring-mvc

我尝试使用Spring MVC和Hibernate运行我的第一个Web应用程序,但是我遇到了一些问题。

GenericDao:

<?php for($i=1; $i<=8; $i++){ 
            $testFormA = $row["test".$i."MeterVol"] / $row["test".$i."TesterVol"]; 
            $testFormB = $testFormA * $row["test".$i."Accuracy"]; 
            $testFinalForm = $testFormB / 100;
?>
          <td><?php echo $testFinalForm ?></td>
<?php } ?>

UserDao.java:

@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;

}

GenericService.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();
    }
}

UserService.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());
        }
    }

}

UserController.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);
    }

}

根context.xml中:

@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;
    }

}

日志:

<?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>

问题:请解释我为什么遇到此问题以及如何解决此错误?

1 个答案:

答案 0 :(得分:3)

通过从@Transactional中移除UserDao来解决此问题的原始问题,因为Service实施负责事务管理,而不是DAO。{/ 1}}需要完成p>

还建议从@Autowired构造函数中删除UserDao,因为构造函数没有参数,即它没有自动装配任何东西。

现在已修复此问题,代码与userService的{​​{1}}字段存在类似问题。

由于Spring使用代理模式,UserController需要UserController实现的接口,而不是类本身。

执行此操作的常用方法是将类重命名为UserService,然后添加名为UserServiceImpl的接口。继续让类UserService的字段userServiceUserController类型。