1

我正在尝试将 Spring 3.1 与 Hibernate 4.1.4 集成,但在从通用 DAO 获取会话时遇到问题。

问题是,如果我使用 getCurrentSession() 我得到一个 NullPointerException 并且 Hibernate 说没有会话绑定到上下文,但是如果我使用 openSession 一切似乎都在工作。不知何故,我觉得我应该使用 getCurrentSession,但找不到问题的根源。

我已经在互联网上搜索了这个,但没有一个解决方案对我有用。

这是我的通用 DAO 代码:

public class GenericDaoHibernateImpl<E, PK extends Serializable> implements GenericDao<E, PK> {

    private Class<E> entityClass;

    protected GenericDataBaseExceptionHandler exceptionHandler;

    private SessionFactory sessionFactory;  

    @SuppressWarnings("unchecked")
    public GenericDaoHibernateImpl() {
        this.entityClass = (Class<E>) ((ParameterizedType) getClass().
            getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public void setExceptionHandler(GenericDataBaseExceptionHandler exceptionHandler) {
        this.exceptionHandler = exceptionHandler;
    }

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

    protected Session getSession() {
        if (sessionFactory.getCurrentSession() == null)
            throw new IllegalStateException("Session has not been set on DAO before usage");
        return sessionFactory.getCurrentSession(); //This crashes
//      return sessionFactory.openSession(); //This does not
    }

    public Class<E> getEntityClass() {
        return entityClass;
    }

    public void persist(E entity) throws GenericDataBaseException {
        try {
            getSession().persist(entity);       
        } catch (Throwable t) {
            Collection<Object> args = new ArrayList<Object>();
            args.add(entity);
            throw exceptionHandler.handle(t, "persist", args);
        }
    }
    (...)

}

还有我的弹簧配置文件:

    <context:annotation-config />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="jdbcUrl">
            <value>jdbc:mysql://localhost/forestool</value>
        </property>
        <property name="user">
            <value>forestool</value>
        </property>
        <property name="password">
            <value>forestool</value>
        </property>
    </bean>


    <!-- Declaración de la factoría de sesiones hibernate con los mappings necesarios -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="mappingLocations">
            <list>
                <value>classpath*:/hbm/*.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <ref bean="hibernateProperties"/>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
     <property name="sessionFactory">
         <ref bean="sessionFactory"/>
     </property>
    </bean>
<bean id="hibernateProperties" class="java.util.Properties">
    <constructor-arg index="0">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
        </props>
    </constructor-arg>
</bean>

例外:

org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1041)
    at es.fsc.core.dao.impl.GenericDaoHibernateImpl.getSession(GenericDaoHibernateImpl.java:83)
    at es.fsc.core.dao.impl.GenericDaoHibernateImpl.findAll(GenericDaoHibernateImpl.java:244)
    at es.fsc.dao.explotacion.impl.ExplotacionDaoImpl.getExplotacionesAbiertas(ExplotacionDaoImpl.java:21)
    at es.fsc.service.explotacion.impl.ExplotacionServiceImpl.getExplotacionesAbiertas(ExplotacionServiceImpl.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
    at $Proxy5.getExplotacionesAbiertas(Unknown Source)
    at es.fsc.app.FscApp.runApp(FscApp.java:58)
    at es.fsc.app.App.run(App.java:65)
    at es.fsc.main.Main.main(Main.java:20)
Exception in thread "main" java.lang.NullPointerException
    at es.fsc.core.dao.impl.GenericDaoHibernateImpl.findAll(GenericDaoHibernateImpl.java:253)
    at es.fsc.dao.explotacion.impl.ExplotacionDaoImpl.getExplotacionesAbiertas(ExplotacionDaoImpl.java:21)
    at es.fsc.service.explotacion.impl.ExplotacionServiceImpl.getExplotacionesAbiertas(ExplotacionServiceImpl.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
    at $Proxy5.getExplotacionesAbiertas(Unknown Source)
    at es.fsc.app.FscApp.runApp(FscApp.java:58)
    at es.fsc.app.App.run(App.java:65)
    at es.fsc.main.Main.main(Main.java:20)
4

1 回答 1

1

我在这个配置中看不到任何实际上会为您打开 Hibernate 会话或控制何时完成的东西。

如果您是 Spring 新手,您可能只想在您的OpenSessionInViewFilterweb.xml中配置一个 Session 打开并自动绑定到每个请求。

于 2012-07-05T16:19:47.277 回答