Usage of JPQL KEY() with entity key generates inner join

Description

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 a Map<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 selecting templateen2_.templateEntries_KEY.
This could be achieved by allowing both KEY(templateEntries) and KEY(templateEntries).id. Hibernate currently does not support dereferencing of KEY() functions but the spec contains examples of similar usages.

Attachments

1

Activity

Show:

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?

[1] http://dba.stackexchange.com/questions/52432/syntax-of-inner-join-nested-inside-outer-join-vs-query-results

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.

Fixed

Details

Assignee

Reporter

Labels

Worked in

Components

Fix versions

Priority

Created February 16, 2016 at 11:01 PM
Updated March 15, 2017 at 12:34 AM
Resolved March 15, 2017 at 12:21 AM