3

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

        });
    }

    ...
}
4

3 回答 3

5

@PostConstruct我认为在级别上不允许进行任何交易,因此除非设置为in ,@Transactional否则不会在这里做太多事情。modeaspectj<tx:annotation-driven mode="aspectj" />

根据讨论,您可以使用TransactionTemplate在内部启动手动事务init()以进行绑定session,但如果您打算严格遵守声明性事务,则需要使用ApplicationListener来注册事件和用户ContextRefreshedEvent来启动事务。

于 2014-03-05T09:56:17.377 回答
0

确保您在事务下运行。我可以看到事务注释,但看起来您错过了通过<tx:annotation-driven/>在 spring 上下文中使用标记来使用注释激活事务管理。

于 2014-03-05T09:45:42.207 回答
0

发生这种情况是因为在相关 bean 构建MyServiceImpl.init()后由 Spring 调用,并且注解不用于管理会话生命周期。 一个解决方案可能是考虑使用缓存而不是使用缓存的方法的 Spring AOPMyServiceImpl@Transaction
@PostConstruct

于 2014-03-05T09:46:14.760 回答