Spring MVC+Hibernate:getCurrentSession获取事务同步Session失败,OpenSession正常
嗨,我来帮你拆解这个问题的常见配置原因~ 你遇到的Could not obtain transaction-synchronized Session for current thread错误,核心是getCurrentSession()依赖Spring的事务同步机制,它需要和当前线程绑定的事务关联,而openSession()是直接创建独立Session,所以能临时绕开问题,但咱们得找到配置上的疏漏,从根源解决。
1. 没启用Spring的事务管理支持
首先得确保Spring能帮你管理事务,这是getCurrentSession()正常工作的基础:
- 在
DB-Config.xml里,必须配置Hibernate事务管理器:
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
- 接着要开启注解驱动的事务支持(如果你用
@Transactional注解的话):
<tx:annotation-driven transaction-manager="transactionManager"/>
要是没加这一步,Spring不会自动绑定事务和Session,getCurrentSession()自然找不到对应的线程绑定Session。
2. SessionFactory的上下文配置错了
Hibernate的SessionFactory得交给Spring来管理上下文,不能用它自带的线程上下文。在DB-Config.xml的SessionFactory配置里,要确保有这个属性:
<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
如果配置成thread或者其他值,Spring就没法把Session和自己的事务同步绑定,导致getCurrentSession()失效。
3. 业务方法没被事务包裹
就算配置了事务管理器,你的Service/DAO方法如果没被事务标记,调用getCurrentSession()时,当前线程没有活跃事务,自然拿不到同步Session。
记得把@Transactional加在Service层方法上(别加在DAO层,事务通常在Service层控制):
@Transactional public User login(String username, String password) { // 这里调用DAO的getCurrentSession()操作数据库 }
4. 组件扫描范围没覆盖Service类
如果你的Service类没被Spring容器扫描到,@Transactional注解就不会生效。检查你的配置文件:
- 如果是用
servlet.xml,注意它通常只扫描Controller层;Service和DAO应该放在根上下文(比如applicationContext.xml)里扫描,确保包路径正确:
<context:component-scan base-package="com.yourpackage.service, com.yourpackage.dao"/>
5. SessionFactory没被正确注入
要是你的DAO里是手动创建SessionFactory,而不是Spring注入的,那Spring的事务管理也没法绑定Session。确保DAO里的SessionFactory是通过依赖注入获取的:
@Repository public class UserDAO { @Autowired private SessionFactory sessionFactory; public User findByUsername(String username) { return sessionFactory.getCurrentSession() .createQuery("from User where username=:username", User.class) .setParameter("username", username) .uniqueResult(); } }
对照上面的点检查你的servlet.xml和DB-Config.xml,应该就能找到问题所在啦~
内容的提问来源于stack exchange,提问作者srik123

