ssh整合时,使用this.getSessionFactory().getCurrentSession(),会报No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional异常。。
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- <prop key="current_session_context_class">thread</prop> -->//单独的hibernate使用
<prop key="hibernate.current_session_context_class">thread</prop>//ssh中使用
</props>
</property>
</bean>
以下是在网上找的原因
<property name="current_session_context_class">thread</property> 这个属性的作用:这样配置是本地jdbc事务配置,你通过getCurrentSession创建的session会绑定到当前线程 平时在单独使用hibernate的时候,习惯于配置属性
<property name="current_session_context_class">thread</property>
根据文档,这个是hibernate3.1以后的一个新扩展,目的在于可以让我们在某一个上下文环境(比如说当前线程)中可以通过
SessionFactory.getCurrentSession()得到同一个session会话.
后来当我们把spring,hibernate整合的时候,在spring的主配置文件当中,我们也习惯于带入这样的配置
<property name="hibernateProperties">
<props>
<prop key="hibernate.current_session_context_class">thread</prop>
,接下来在spring配置文件中,会使用spring2.x的声明式的方式来配置事务
<tx:advice id="txAdvice" transaction-manager="transactionManager">,<aop:pointcut,<aop:advisor等等配置指定哪些方法上由spring来管理hiberante的事务,这个时候我们试着运行一个类似于这样的方法
public void find() {
Session se = sf.getCurrentSession();
//此处不需要se.beginTransaction(),事务已经交由spring管理
Dept d = (Dept) se.get(Dept.class, new Long(12));
}
会得到一个异常: get is not valid without active transaction.
这个错误一般情况是因为由getCurrentSession得到的session中没有获得的transaction,我们一般要手动的调用se.beginTransaction(),来打开一个活动的事务.但是问题是,我们在spring的配置文件中不是已经通过aop,指定了此处由spring来管理事务吗,怎么还要手动处理事务?
答案:
<prop key="hibernate.current_session_context_class">thread</prop>改为
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>(默认配置)
参考:
1. hibernate文档:
2.在hibernate中,thread,jta,manager的配置其实都是对应了3个hibernate的实现类
3.在sessionFactory配置文件中
|