我使用Spring + Hibernate + JPA和Tomcat 7进行REST服务。当我启动应用程序时,我得到以下内容:
org.apache.catalina.core.ApplicationContext log org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'carService': Error creating bean with name 'carServiceImpl': Unsatisfied dependency expressed through field 'carDao': Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'carServiceImpl': Unsatisfied dependency expressed through field 'carDao': Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'carServiceImpl': Unsatisfied dependency expressed through field 'carDao': Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
下面我展示了我的spring配置类
@Configuration
@Import(DispatcherServletConfig.class)
@ComponentScan(basePackages = "org.parkingTracker.controller, org.parkingTracker.service, org.parkingTracker.dao")
@ImportResource("classpath*:/dao/src/main/resources/spring/dao-context.xml")
public class RootConfig {
public RootConfig() {}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "org.parkingTracker.controller, org.parkingTracker.service")
public class DispatcherServletConfig {
public DispatcherServletConfig() {}
}
我还有用于访问数据的服务和dao类。要在我的dao中注入EntityManager我正在使用@PersistenceContext
注释,对于服务类的注入dao我使用简单的spring注释。下面你可以看到我的spring xml配置DAO布局。 一个重要的评论,当我为所有正确的dao类运行测试时,我没有任何异常,我正在获取有效数据
<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:tx="http://www.springframework.org/schema/tx"
xmlns:jpa = "http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">
<context:component-scan base-package="org.parkingTracker.dao"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/parking"/>
<property name="username" value="postgres"/>
<property name="password" value="a1f10g"/>
<property name="initialSize" value="20"/>
<property name="maxActive" value="100"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
</bean>
</property>
<property name="packagesToScan" value="org.parkingTracker.model"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL94Dialect</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<jpa:repositories base-package="org.parkingTracker"
entity-manager-factory-ref="emf"
transaction-manager-ref="transactionManager"/></beans>
CarServiceImpl:
public class CarServiceImpl implements CarService {
@Autowired
private CarDao carDao;
@Override
public void saveCar(Car car) throws EntityAlreadyExistException {
carDao.saveCar(car);
}
@Override
public Car getCarById(int id) {
return carDao.getCarById(id);
}
@Override
public Car getCarByIdWithTimeSpend(int id) {
return carDao.getCarByIdWithTimeSpend(id);
}
@Override
public Car getCarByNumber(String number) {
return carDao.getCarByNumber(number);
}
@Override
public Car getCarByNumberWithTimeSpend(String number) {
return carDao.getCarByNumberWithTimeSpend(number);
}
CarDao:
@Transactional
@Repository("carDao")
public class CarDaoImp implements CarDao{
private final String EXIST_SQL = "SELECT 1 FROM car WHERE car_num = :num";
@PersistenceContext
private EntityManager entityManager;
@Transactional()
public void saveCar(Car car) throws EntityAlreadyExistException {
if(entityManager.createNativeQuery(EXIST_SQL).setParameter("num", car.getNumber()).getSingleResult()!=null){
throw new EntityAlreadyExistException();
}else {
entityManager.persist(car);
}
}
@Transactional(readOnly = true)
public Car getCarById(int id) {
return entityManager.find(Car.class, id);
}
@Transactional(readOnly = true)
public Car getCarByIdWithTimeSpend(int id) {
Car car = entityManager.find(Car.class, id);
Hibernate.initialize(car.getTimeSet());
return car;
}
@Override
@Transactional(readOnly = true)
public Car getCarByNumber(String number) throws NoResultException{
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> carCriteriaQuery = entityManager.getCriteriaBuilder().createQuery(Car.class);
Root<Car> root = carCriteriaQuery.from(Car.class);
carCriteriaQuery.select(root);
carCriteriaQuery.where(builder.equal( root.get(Car_.number), number ));
return entityManager.createQuery(carCriteriaQuery).getSingleResult();
}
@Override
@Transactional(readOnly = true)
public Car getCarByNumberWithTimeSpend(String number){
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Car> carCriteriaQuery = entityManager.getCriteriaBuilder().createQuery(Car.class);
Root<Car> root = carCriteriaQuery.from(Car.class);
carCriteriaQuery.select(root);
carCriteriaQuery.where(builder.equal( root.get(Car_.number), number ));
Car car = entityManager.createQuery(carCriteriaQuery).getSingleResult();
Hibernate.initialize(car.getTimeSet());
return car;
}
}
web.xml:
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextClass</param-name>
<param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
org.parkingTracker.controller.config.RootConfig
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value> org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
org.parkingTracker.controller.config.DispatcherServletConfig
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
答案 0 :(得分:1)
似乎IOC容器未能注入EntityManagerFactory
到CarDaoImp
。我看了你的代码,似乎你定义了所有必要的配置,我认为问题在于你的XML配置文件加载。
尝试使用classpath:your_xml_config.xml
,但没有文件夹结构前缀。像这样:
@Configuration
@Import(DispatcherServletConfig.class)
@ComponentScan(basePackages = "org.parkingTracker.controller, org.parkingTracker.service, org.parkingTracker.dao")
@ImportResource("classpath:dao-context.xml")
public class RootConfig {
public RootConfig() {}
}