We are updating a project from Querydsl version 3 to version 4. The way sub-queries work changed. In version 3, you could write a sub-query like this:
ListSubQuery<Long> subQueryResult = new JPASubQuery()
.from(domain)
.where(domain.prefix.eq(prefix))
.list(domain.id);
I upgraded the code to:
JPQLQuery<Long> subQueryResult = from(domain)
.select(domain.id)
.where(domain.prefix.eq(prefix))
.fetchAll();
My question is about the method fetchAll I added at the end of the query. I'm not sure if it's necessary. I assumed it was a replacement for list, but my colleague pointed out the return type is just JPQLQuery, which is already returned by where.
JavaDoc for fetchAll states:
Add the "fetchJoin all properties" flag to the last defined join.
Which means nothing to me. Experiments seem to indicate that the call is not necessary, but that still leaves the question - what is it for? And can I safely remove it from my sub-query?
You need a fetchJoin()
to actually load properties marked as "lazy" eagerly. That does not mean much for your example (only loading a domain.id
value), but if you start to load complex data types in a subquery, you might actually want your data to be present for your root query.
That being said, having a complex data type with "lots of" lazy attributes, you might not want / need to add the fetch flag to all of them, but only to those you actually need for the query. So just calling fetchAll might not be what you need all the time. When in doubt, I would suggest to enable sql logging and analyse the generated sql, each JOIN FETCH
being an eager load.
And can I safely remove it from my sub-query
So the TL;DR: if you never had to think about JOIN FETCH
in the past, then actually: yes, you should be able to safely ignore the fetchAll
, as it would not add anything new to your queries. It should just be a convenient way to spare you some boilerplate code in case you actually want a full eager load of your data.