0

我正在使用 Spring 3.0.2 版。我想通过@Transactional注释管理事务。

applicationContext.xml文件中,我有以下数据源配置。

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"
      p:driverClassName="oracle.jdbc.OracleDriver"
      p:url="jdbc:oracle:thin:@localhost:1521:xe"
      p:username="userName"
      p:password="password"/>

SessionFactory配置如下。

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="mappingResources">
  <list>
    <value>hibernate.cfg.xml</value>
  </list>
  </property>
  <property name="hibernateProperties">
    <value>
      hibernate.dialect=org.hibernate.dialect.OracleDialect
    </value>
  </property>
</bean>

hibernate.cfg.xml文件位于默认包中。


<bean id="transactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager"
      p:sessionFactory-ref="sessionFactory" />

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

<bean id="CountryService"
      class="dao.CountryDAO"
      p:sessionFactory-ref="sessionFactory" />

CountryService界面简单如下。

package daoservice;

import java.util.List;
import model.Country;

public interface CountryService
{
    public List<Country>getAllCountries();
}

以下是它的实现 - CountryDAO.

package dao;

import daoservice.CountryService;
import java.util.List;
import model.Country;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(readOnly = true)
final public class CountryDAO implements CountryService
{
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
        System.out.println("template = "+this.sessionFactory);
    }

    @SuppressWarnings("unchecked")
    public List<Country>getAllCountries() throws DataAccessException
    {
        System.out.println("sessionFactory = "+sessionFactory);
        return sessionFactory.getCurrentSession().createQuery("from model.Country order by countryId desc").list();
    }
}

关于部署时间,下面的语句,

System.out.println("template = "+this.sessionFactory);

如在setSessionFactory()方法中显示类似

template = org.hibernate.impl.SessionFactoryImpl@c63558

这意味着在applicationContext.xml文件中进行的上述配置似乎有效。


getAllCountries()但是从我的 Spring 控制器类中调用前一个类中的方法,例如(在 GET 方法期间)

CountryDAO c=new CountryDAO();
List<Country> countryList = c.getAllCountries();

导致NullPointerException抛出和语句

System.out.println("sessionFactory = "+sessionFactory);

显示

sessionFactory = null

很明显。


据推测,似乎是由构造函数创建了一个新实例,CountryDAO并且对象在其中sessionFactory变为null.

那么如何使用CountryDAOSpring(或其他地方)的 DAO?


根据答案尝试,它抛出了以下异常。

org.springframework.beans.factory.BeanCreationException:创建名为“countryController”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private dao.CountryDAO controller.CountryController.countryDAO; 嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为 [dao.CountryDAO] 的匹配 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

4

1 回答 1

1

您需要从 中获取CountryDAObean,WebApplicationContext或者通过 xml 或注释将其注入到您的控制器中。像这样的东西:

@Controller
public class SomeController{

    @Autowired
    private CountryService CountryService;

    // Getters and Setters

}

您正在做CountryDAO c=new CountryDAO();的只是实例化一个不受弹簧容器管理的新对象,因此它当然会将其会话工厂设置为null.

于 2012-12-11T05:07:01.233 回答