缓存延迟加载来自open-session-in-view的延迟加载关系的集合

时间:2015-12-08 12:57:30

标签: hibernate caching lazy-loading second-level-cache open-session-in-view

我有这种情况(详情见底部):

  • X是一个休眠实体
  • X.y是对Y的延迟加载引用,另一个是hibernate实体
  • Y.z是一个延迟加载,缓存的hibernate实体Z
  • 的集合

在事务后的Spring bean中,在open-session-in-view中,我访问Xyz并得到" org.hibernate.HibernateException:无法解析加载集合的所有者[... ]用于二级缓存"。 调试到Hibernate 4.3.8.Final我发现X.y是使用临时会话延迟加载的,因此在"原始" StatefulPersistenceContext,其中CollectionLoadContext正在寻找它。

我做的事情还没有完成吗?我是否需要事先明确触发此延迟加载或删除缓存?

public class Teachable {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fk_org_element_sch", nullable = false)
    protected ElementSch element;
}

public class ElementSch {
    @OneToMany(targetEntity = ElementConnectionSch.class)
    @JoinColumn(name = "fk_org_element_parent")
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Collection<ElementConnectionSch> childConnections;
}

public class ElementConnectionSch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="fk_org_element_parent")
    private ElementSch parent;
}

在提交了transacation之后,但仍然在open-session-in-view中,我正在调用Teachable.getElement()。getChildConnections()并获取HibernateException。从调试中我可以看到ElementSch和ElementConnectionSch在单独的会话中被延迟加载,即主会话已加载Teachable,并且ElementSch和ElementConnectionSch使用了两个单独的临时会话。

1 个答案:

答案 0 :(得分:0)

由于Hibernate版本升级,我们已经发现这是一个问题:

我们使用Spring WebFlow并将Hibernate实体放入流范围。为了使它在流程中的多个调用之间正常工作,我们将实例和集合重新附加包装器,以便它们接收正在进行的调用的会话,而不是使用它们创建的那个,现在已关闭。

随着版本升级,对注入的执行方式进行了更改,虽然正常工作,但是在加载原始映射之前>应用了,即我们循环遍历空迭代器并且不注入任何内容。