【问题标题】:No Session Hibernate in @PostConstruct@PostConstruct 中没有会话休眠
【发布时间】:2014-03-05 09:27:37
【问题描述】:

MyDao 类具有通过 Hibernate SessionFactory 完成整个持久性任务的方法,它工作正常。

如上所示,我在 MyService 中注入了 MyDao,但是在注入 MyDao 后调用 @PostConstruct init() 方法时(调试我可以看到 MyDao 注入良好)得到下一个 Hibernate 异常:

org.hibernate.HibernateException: No Session found for current thread

我的服务实现。

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

        });
    }

    ...
}

【问题讨论】:

  • 您的代码有一个“空白”,我不希望有一个:public void MyServiceImpl。这应该是构造函数还是您从其他地方调用的方法?

标签: spring hibernate postconstruct


【解决方案1】:

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

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

【讨论】:

  • 非常感谢,TransactionTemplate 对我来说工作得很好。 ;)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 2018-09-27
      • 2013-09-14
      相关资源
      最近更新 更多