| 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):
SELECT d.name, KEY(templateEntries) FROM Document d
LEFT JOIN d.documentVersions versions
LEFT JOIN versions.templateEntries templateEntries
Hibernate 5.1.0.Final generates the following query:
select document0_.name as col_0_0_, templateen2_.templateEntries_KEY as col_1_0_, template4_.id as id1_3_
from Document document0_
left outer join DocumentVersion documentve1_ on document0_.id=documentve1_.document_id
left outer join DocumentVersion_TemplateEntry templateen2_ on documentve1_.id=templateen2_.DocumentVersion_id
left outer join TemplateEntry templateen3_ on templateen2_.templateEntries_id=templateen3_.id
inner join Template template4_ on templateen2_.templateEntries_KEY=template4_.id;
Hibernate 4.3.8.Final generates the following query:
select document0_.name as col_0_0_, templateen2_.templateEntries_KEY as col_1_0_, templateen3_.id as id1_4_
from Document document0_
left outer join DocumentVersion documentve1_ on document0_.id=documentve1_.document_id
left outer join DocumentVersion_TemplateEntry templateen2_ on documentve1_.id=templateen2_.DocumentVersion_id
left outer join TemplateEntry templateen3_ on templateen2_.templateEntries_id=templateen3_.id;
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. |