【问题标题】:Spring + Hibernate + DAO + SessionFactory + InjectSpring + Hibernate + DAO + SessionFactory + Inject
【发布时间】:2012-06-10 11:21:52
【问题描述】:

我将 Spring 与 Hibernate 一起使用,并且总是为 sessionFactory 对象获取 NPE。

我的配置文件:

@Configuration
public class HibernateConfiguration {

@Bean
public AnnotationSessionFactoryBean sessionFactory() {
    Properties props = new Properties();
    props.put("hibernate.dialect", MySQL5InnoDBDialect.class.getName());
    props.put("hibernate.format_sql", "true");
    props.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
    props.put("hibernate.connection.password", "xxx");
    props.put("hibernate.connection.url", "jdbc:mysql://localhost/Market");
    props.put("hibernate.connection.username", "philipp");

    AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
    bean.setAnnotatedClasses(new Class[] { xxx.class, xxx.class, xxx.class });
    bean.setHibernateProperties(props);
    bean.setSchemaUpdate(true);
    return bean;
}





@Bean
public HibernateTransactionManager transactionManager() {
    return new HibernateTransactionManager(sessionFactory().getObject());
}

@Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
    return new PersistenceExceptionTranslationPostProcessor();
}

}

我的 DAOImpl 类:

@Repository("xxx")
public class xxxDAOImpl implements xxxDAO {

private SessionFactory sessionFactory;

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
}

private Session currentSession() {
    return sessionFactory.getCurrentSession();
}
...

测试用例:

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class TestxxxDAOImpl {

@Test
@Transactional
public void testInsertxxx() throws Exception {

    xxxDAO xxxDAO = new xxxDAOImpl();
    xyz xyz = new xyz();
    xxxDAO.insert(xyz);
    assertNotNull(xyz.getId());
    }

}

app-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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"   xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
    http://www.springframework.org/schema/jdbc   http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan base-package="xxx.config" />
<context:component-scan base-package="xxx.dao" />
<context:annotation-config></context:annotation-config>

测试上下文.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:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<import resource="classpath:/META-INF/spring/app-context.xml" />

当测试调用 insert 方法时,我总是从 currentSession 中得到一个 NPE。

public void insert(xxx xxx) {
    currentSession().save(xxx);
}


private Session currentSession() {
    return sessionFactory.getCurrentSession();
}

【问题讨论】:

    标签: spring hibernate sessionfactory


    【解决方案1】:

    使用 Spring 时首先要了解的是,Spring 依赖注入仅适用于从应用程序上下文获取的 bean,不适用于使用 new 创建的 bean。

    在启用 Spring 的单元测试中,您可以使用 @ContextConfiguration 配置应用程序上下文,例如,如下所示(在 Spring 3.1 中工作,在以前的版本中,@ContextConfiguration 不直接采用 @Configuration 类,因此您将拥有创建 XML 配置文件):

    @Configuration 
    public class HibernateConfiguration { 
        // Add your DAO to application context
        @Bean
        public xxxDAO xxxDAO() {
            return new xxxDAOImpl();
        }
        ...
    }
    
    // Configure application context using the given @Configuration class
    @ContextConfiguration(classes = HibernateConfiguration.class)   
    @RunWith(SpringJUnit4ClassRunner.class)
    public class TestxxxDAOImpl {
        // Obtain DAO from the application context    
        @Autowired xxxDao xxxDao;
        ...
    }
    

    【讨论】:

    • 这不适用于多个配置。自动接线没有名字。
    【解决方案2】:

    使用 sessionFactory.openSession() 代替 xxxDAOImpl 类的 currentSession() 函数中的 sessionFactory.getCurrentSession()。

    由于在您的第一次调用中,会话工厂中不会有任何当前会话,因此您需要打开会话。

    希望这对您有所帮助。干杯。

    【讨论】:

    • 应该注入 sessionFactory,所以我的 xxxDAOImpl 类中总是有一个会话。问题是 Spring 没有注入 sessionFactory。
    • 我建议您再次正确检查NPE点。正如我所说,我怀疑问题出在 getCurrentSession 中。请在此处显示您的堆栈跟踪,以便我可以很好地理解。
    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 2013-06-07
    • 2017-05-04
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    相关资源
    最近更新 更多