Reputation: 329
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.
Upvotes: 4
Views: 735
Reputation: 12122
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.x.x.
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);
Upvotes: 1