QueryDSL JPA - Don't JOIN twice

82 views
Skip to first unread message

julia...@gmail.com

unread,
Oct 17, 2017, 4:41:55 AM10/17/17
to Querydsl
Hello,

I have a project that consists most of CRUDs, with JSF, JPA and QueryDSL JPA as helper library.

I have the need to do queries with dynamic WHERE and ORDER BY, for real (lazy) pagination.

For some filters, I only want to do the JOIN and the WHERE if some filter was filled. In other words:

pseudocode
if filter was filled
     
do JOIN
     
do WHERE
end if

Problem is, I have some filters that use the same JOIN.

If I fill both filters, the same JOIN is added twice to the query.

Is there a native way to QueryDSL do something like this:

pseudocode
if JOIN was added
    ignore JOIN
(or reuse existing JOIN)
end if

Is that possible?

Richard Richter

unread,
Oct 18, 2017, 9:17:15 AM10/18/17
to Querydsl
Hi

We did something similar. What you should do in any case is use some kind of "alias" for joined relation, e.g.
QOwner o = new QOwner("o"); // alias
and in the query... .join(dog.owner, o)...

Now anytime you want to do this, it's possible to investigate the metadata of the query: QueryMetadata metadata = query.getMetadata();
Next investigate the list returned by: metadata.getJoins()

I don't have production-ready example, so I recommend you to try it, debug it, but it is possible to get the answer to the question "hey, query, do you have this join with this alias already?"

If you don't want to deal with metadata, you can still use some kind of set, where you store the aliases that are in the query already:
if (filter.getAttribute() != null) {
   addMissingJoinForAlias(query, aliasX); // this is called always, but inside has check of the set with join already added
   query.where(aliasX.attribute.eq(...)); // or whatever predicate using that alias
}

So yes, it is possible, and you can either introspect metadata of the query or do it yourself. Both has pros and cons.

Cheers

Richard "Virgo" Richter
Reply all
Reply to author
Forward
0 new messages