@PostConstruct中没有会话休眠

时间:2014-03-05 09:27:38

标签: spring hibernate postconstruct

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;
            }

        });
    }

    ...
}

3 个答案:

答案 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}}

的方法,解决方案可能会考虑使用Spring AOP