我有一个bean(SettingService),它用@Transactional注释修饰并注入到另一个bean中,在上面刷新的事件中调用这个bean。
public class DefaultConfigManager
implements ApplicationListener<ContextRefreshedEvent>, ConfigManager {
@Autowired
private SettingService service;
@Override
public void onApplicationEvent( ContextRefreshedEvent event ) {
System.out.println( "Proxy: " + AopUtils.isJdkDynamicProxy( service ) );
String key = service.getSystemSetting( "KEY" );
}
事务通常运行良好,上面的方法在Spring 4.1.9中按预期工作,其中println指示SettingService bean是动态JDK代理(用于事务处理)。
现在升级到Spring 4.2.5后,突然开始抛出以下错误:
org.hibernate.HibernateException:无法获取当前线程的事务同步会话
at org.springframework.orm.hibernate4.SpringSessionContext。 currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl。的getCurrentSession(SessionFactoryImpl.java:993)
并且println表示SettingService不再是代理/已被修饰,这意味着不会启动任何事务。
根据Spring文档,在发布ContextRefreshedEvent时,应该完成所有bean和后处理器。
在应用程序上下文中配置了Hibernate事务管理器,tx:annotation-driven元素就位,@Transactional注释放在实现(不是接口)上,系统中没有循环依赖。 Hibernate版本:4.2.20.Final。
这对任何人都响了吗?是否有任何典型的原因导致为什么bean不再应该在Spring 4.2中的ContextRefreshedEvent上用事务代理? Spring 4.1和4.2之间的任何常见错误或变化都要注意?
答案 0 :(得分:2)
我遇到了同样的问题。我的解决方法是将@Transactional注释放在类级别而不是方法级别。