Hibernate @Async未来结果和Lazy初始化异常

时间:2015-07-01 09:02:22

标签: java spring hibernate

我有一些服务方法的控制器方法,我想用它们paralllel。

控制器方法

public String (...) {
    Future<List<Obj1>> obj1Result= asyncDelegate.getAllObj1();
    Future<List<Obj2>> obj2Result= asyncDelegate.getAllObj2();
    Future<List<Obj3>> obj3Result= asyncDelegate.getAllObj3();

    while(!(obj1Result.isDone() && obj2Result.isDone() && obj3Result.isDone())) {
        Thread.sleep(10);
    }
    model.addAttribute(...);
    return "view";
}

我也有@Async标记方法的委托服务,它返回@Transactional服务的未来结果

@Component
public class AsyncDelegate {

Logger logger = Logger.getLogger(getClass());

@Async
public Future<List<Obj1>> getAllObj1() {
    return new AsyncResult<List<Obj1>>(obj1Service.getAll());
}

@Async
public Future<List<Obj2>> getAllObj2() {
    return new AsyncResult<List<Obj2>>(obj2Service.getAll());
}

@Async
public Future<List<Obj3>> getAllObj3() {
    return new AsyncResult<List<Obj3>>(obj3Service.getAll());
}

}

Obj1,Obj2,Obj2有​​懒惰的初始化集合,在视图中加载它我用

<filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
     <async-supported>true</async-supported>
</filter>

最后在生成视图中我得到了

 ERROR org.hibernate.LazyInitializationException:42 - failed to lazily initialize a collection of role: obj.lazy-collection, no session or session was closed

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

你的问题是Spring正在运行ThreadLocal中的所有hibernate配置,并且你正在创建具有自己的本地线程的新线程,其中Hibernate会话不存在。

因此,如果已经在前一个线程中创建了这些实体,则需要初始化这些实体的会话,否则hibernate无法初始化那些hibernate代理实体,因为会话不存在。

答案 1 :(得分:0)

当您确定它们将在加载它们的会话之外使用时,您可以显式初始化代理:

Hibernate.initialize(obj.getLazyCollection());

您可以在加载obj的同一事务中调用此项。