Hibernate:无法急切地获取子集合的子集合

时间:2016-03-07 14:53:41

标签: java hibernate eager-loading

我有一个Session类,它有一个Photo对象的映射集合:

@OneToMany(fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name = "sessionId", insertable = false, updatable = false)
private SortedSet<Photo> photos = new TreeSet<>();

每张照片都有一组评论对象,被指定为FetchType.LAZY(因为我不总是想要它们):

@OneToMany(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
@BatchSize(size=20)
@Fetch(FetchMode.SUBSELECT)
@JoinColumn(name = "photoId", insertable = false, updatable = false)
private SortedSet<Comment> comments = new TreeSet<>();

在我对Sessions的查询中,我希望能够以编程方式即时决定是否包含评论。我尝试过(以及其他变体):

Criteria criteria = hibSession.createCriteria(Session.class, "s")
    .createAlias("photos", "p")
    .setFetchMode("p.comments", FetchMode.JOIN);

但那并不是这样。在任何返回的Photo子对象上调用photo.getComments()会抛出LazyInitializationException

如果我(仍在原始Hibernate会话的范围内)迭代所有Sessions,并在所有Photos中,并调用photo.getComments().size(),那将获取注释(按指定批量)。

但有没有办法告诉初始查询只是第一次急切地所有评论,而不需要事后迭代?

感谢。

1 个答案:

答案 0 :(得分:0)

它可能是众所周知的App::instance错误HHH-3524HibernatesetFetchMode查询中没有按预期工作。它被关闭作为陈旧问题,但一些用户报告它为Hibernate版本4.x.x。

要解决此问题,您可以使用Criteria,因为它可以正常运行:

HQL

或使用session.createQuery("SELECT s FROM PhotoSession s " + "JOIN FETCH s.photos p " + "JOIN FETCH p.comments"); 的解决方案解决方案:

createCriteria(associationPath, JoinType.LEFT_OUTER_JOIN)