简体   繁体   中英

Hibernate: Unable to eagerly fetch child collection of a child collection

I have a Session class, which has a mapped collection of Photo objects:

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

Each Photo in turn has a collection of Comment objects, which is designated as being FetchType.LAZY (because I don't always want them):

@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<>();

In my query for Sessions, I'd like to be able to programmatically decide, on-the-fly, whether to include the Comments or not. I've tried (among other variations):

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

But that doesn't do it. Calling photo.getComments() on any of the returned Photo sub-objects throws a LazyInitializationException .

If I (still within the scope of the original Hibernate session) iterate over all the Sessions, and within that all the Photos, and call photo.getComments().size() , that will fetch the Comments (in batches, as specified).

But is there any way to tell the initial query to just eagerly get all the Comments the first time around, without the need to iterate afterwards?

Thanks.

It's probably well known Hibernate bug HHH-3524 , setFetchMode doesn't work as expected in Criteria queries. It was closed as stale issue, but some users report it for Hibernate versions 4.xx

To fix that you can use HQL since it works properly:

session.createQuery("SELECT s FROM PhotoSession s " +
    "JOIN FETCH s.photos p " +
    "JOIN FETCH p.comments");

Or use workaround solution with createCriteria(associationPath, JoinType.LEFT_OUTER_JOIN) :

Criteria criteria = session.createCriteria(PhotoSession.class, "s");
criteria.createAlias("photos", "p");
criteria.createCriteria("p.comments", "c", JoinType.LEFT_OUTER_JOIN);
criteria.setFetchMode("c", FetchMode.JOIN);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM