MyDao类有通过Hibernate SessionFactory完成整个持久化任务的方法,它工作正常。
我在MyService中注入MyDao,如上所示,但是在注入MyDao后调用@PostConstruct init()方法(调试我可以看到MyDao注入良好)获取下一个Hibernate异常:
org.hibernate.HibernateException:找不到当前线程的会话
我的服务实施。
@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {
@Autowired
private MyDao myDao;
private CacheList cacheList;
@PostConstruct
public void init() {
this.cacheList = new CacheList();
this.cacheList.reloadCache(this.myDao.getAllFromServer());
}
...
}
解决方法
正如我在上面推荐的 @ Yogi ,我使用了TransactionTemplate来获得一个有效/活跃的事务会话,在这种情况下我已经实现了构造函数并且工作正常我
@Service("myService")
@Transactional(readOnly = true)
public class MyServiceImpl implements MyService {
@Autowired
private MyDao myDao;
private CacheList cacheList;
@Autowired
public void MyServiceImpl(PlatformTransactionManager transactionManager) {
this.cacheList = (CacheList) new TransactionTemplate(transactionManager).execute(new TransactionCallback(){
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
CacheList cacheList = new CacheList();
cacheList.reloadCache(MyServiceImpl.this.myDao.getAllFromServer());
return cacheList;
}
});
}
...
}
答案 0 :(得分:4)
我认为 @PostConstruct
级别不允许进行任何交易,因此 @Transactional
在此处不会做太多事情,除非{{1在 mode
中设置为aspectj
。
根据this讨论,您可以使用TransactionTemplate
在<tx:annotation-driven mode="aspectj" />
内启动手动事务来绑定init()
,但如果您打算严格遵守声明式事务,则需要使用ApplicationListener
注册事件和用户ContextRefreshedEvent
以启动交易。
答案 1 :(得分:0)
确保您在交易下运行。我可以看到事务注释,但看起来你错过了通过在spring上下文中使用<tx:annotation-driven/>
标记使用注释来激活事务管理。
答案 2 :(得分:0)
这是因为MyServiceImpl.init()
相关bean构造后MyServiceImpl
被@Transaction
调用,而@PostConstruct
注释不用于管理会话生命周期。
对于使用缓存而不是{{1}}