Uploaded image for project: 'Hibernate ORM'
  1. Hibernate ORM
  2. HHH-10537

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

    Details

    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Worked in:
    • Last commented by a user?:
      true

      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):

         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.

        Attachments

          Issue links

            Activity

              People

              • Votes:
                1 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: