Hibernate SessionFactory becomes null when trying to use it by invoking a method of the same DAO from the Spring MVC controller class

StackOverflow https://stackoverflow.com/questions/13797487

I'm using the Spring version 3.0.2. I want to manage transactions through the @Transactional annotation.

In the applicationContext.xml file, I have the following data source configuration.

<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"/>

The SessionFactory has been configured as follows.

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

The hibernate.cfg.xml file is located in the default package.


<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" />

The CountryService interface is simply as follows.

package daoservice;

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

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

and the following is its implementation - 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();
    }
}

On the deployment time, the following statement,

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

as in the setSessionFactory() method displays something like

template = org.hibernate.impl.SessionFactoryImpl@c63558

This means that the above configurations made in the applicationContext.xml file seem to work.


But invoking the method getAllCountries() as in the preceding class from my Spring controller class like (during the GET method)

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

causes the NullPointerException to be thrown and the statement

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

displays

sessionFactory = null

as obvious.


Presumably it appears that a new instance is created by the constructor of CountryDAO and in which the sessionFactory object becomes null.

So how to use the DAO CountryDAO from Spring (or somewhere else)?


Tried according to the answer, it threw the following exception.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'countryController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private dao.CountryDAO controller.CountryController.countryDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [dao.CountryDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

有帮助吗?

解决方案

You need to get the CountryDAO bean from the WebApplicationContext or get it injected in your controller by xml or annotations. Something like this:

@Controller
public class SomeController{

    @Autowired
    private CountryService CountryService;

    // Getters and Setters

}

What you are doing with CountryDAO c=new CountryDAO();is just to instanciate a new object that is not managed by the spring container, so of course it will have its session factory set to null.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top