Usage of JPQL KEY() with entity key generates inner join
Description
Attachments
caused by
is followed up by
relates to
required for
Activity
Former user March 15, 2017 at 12:21 AM
Fixed in 5.1 branch as well.
Christian Beikov January 27, 2017 at 8:37 PM
@steve: I just learned that ANSI SQL supports a notion of grouping joins with parenthesis[1] which has the same effect as inheriting the join type. I'm not sure if that could actually improve performance but EclipseLink renders joins like that. Maybe rendering the join that way might be desireable for 6.0?
Moritz Becker March 1, 2016 at 12:52 PM
I created a separate issue for key path dereferencing with a test project:
Steve Ebersole February 26, 2016 at 6:25 PM
Ugh, that's right. This unfortunately needs to be an INNER join because of how some Hibernate internals work. You can see the conversation with myself at : https://github.com/hibernate/hibernate-orm/commit/3cdc4476542424bf9a306c79fac3beb2a2580657#diff-29d4baebcef7372adcd40f9a36d81bbcR79
I expect this to be addressed in the work we are doing to rewrite the query parser, but unfortunately I don't see a way to fix it before that.
Steve Ebersole February 26, 2016 at 6:13 PM
The issue of not allowing a KEY path to be dereferenced is a separate issue. Please open a new bug for that with a test.
IMO this issue is best to look at not using the inner join here. Ideally I'd like to see KEY(templateEntries).id
supported with .id
indicating to skip the join altogether.
It seems that the handling of JPQL
KEY()
functions has changed in Hibernate 5.1.0.Final in comparison to Hibernate 4.3.8.Final.I have attached a test project that illustrates the issue. Following JPQL query is used (
templateEntries
is aMap<Template, TemplateEntry>
, both entities):Hibernate 5.1.0.Final generates the following query:
Hibernate 4.3.8.Final generates the following query:
So Hibernate 5 effectively fetches the key whereas Hibernate 4.3.x only selects the id of the key.
In my case, the behavior of Hibernate 5 causes an issue due to the inner join introduced which effectively dumps all documents without
templateEntries
(which I specifically aimed to prevent by using left joins). Obviously, this use case worked with Hibernate 4.3.x.Changing the inner join to a left join would fix this concrete case.
I had a quick look in the spec and it seems that it does not define whether the use of
KEY()
should fetch the key or not, though the Hibernate 5 way feels "more right". However, it would be nice to have a way to only select the id of a key and thereby eliminating the need for the fetch join by just selectingtemplateen2_.templateEntries_KEY
.This could be achieved by allowing both
KEY(templateEntries)
andKEY(templateEntries).id
. Hibernate currently does not support dereferencing ofKEY()
functions but the spec contains examples of similar usages.