springMvc4+hibernate4项目运行报错如下:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
Dao层session的获取的方式如下
@Autowired
private SessionFactory sessionFactory;
protected Session session() {
return sessionFactory.getCurrentSession();
}
spring-context.xml中配置的是注解事务
<!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
网上居然有人说hibernate4不支持hibernate3的 getcurrentSession,建议你用openSession。 的确使用openSession就不会报错了,但这种说法显然是误导大众了。hibernate4 也支持getcurrentSession 会自动关闭session,如果使用openSession 要自己手动关闭。并且自己openSession就不属于hibernate4管理了,每查一次就手动关一次。
使用 hibernate4,在不使用OpenSessionInView模式时,在使用getCurrentSession()时会有如下问题:
当有一个方法list 传播行为为Supports,当在另一个方法getPage()(无事务)调用list方法时会抛出org.hibernate.HibernateException: No Session found for current thread 异常。 这是因为getCurrentSession()在没有session的情况下不会自动创建一个,不知道这是不是Spring3.1实现的bug,欢迎大家讨论下。
<!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
<!-- 定义事务规则 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="merge*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="put*" propagation="REQUIRED" />
<tx:method name="gen*" propagation="REQUIRED" />
<tx:method name="complete*" propagation="REQUIRED" />
<tx:method name="import*" propagation="REQUIRED" />
<tx:method name="open*" propagation="REQUIRED" />
<tx:method name="publish*" propagation="REQUIRED" />
<tx:method name="init*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="*Change*" propagation="REQUIRED" />
<!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 定义事务入口 -->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.acts.web.modules.*.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>