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

Case/when in criteria with string literal result fails type checking

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 4.3.6
    • Fix Version/s: 5.0.5
    • Component/s: None
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true
    • Sprint:

      Description

      Root<User> u = criteria.from(User.class);
      criteria.multiselect(
          u.get("username"),
          cb.selectCase()
              .when(
                  cb.equal(
                      cb.length(u.get("homeAddress").<String>get("zipcode")), 5
                  ), "Germany"
              )
              .when(
                  cb.equal(
                      cb.length(u.get("homeAddress").<String>get("zipcode")), 4
                  ), "Switzerland"
              )
              .otherwise("Other")
      );
      
      Caused by: org.hibernate.QueryException: Could not determine data type for searched case statement
      	at org.hibernate.hql.internal.ast.tree.SearchedCaseNode.getDataType(SearchedCaseNode.java:80)
      	at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:172)
      	at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:924)
      	at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:692)
      	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:665)
      	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
      	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
      	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
      	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
      

      The strings in the criteria query are always transformed into parameters, even if you use CriteriaBuiler#literal(). This implicit parameter binding mechanism of all literals in criteria queries conflicts with the type checking in the SearchedCaseNode. The ParameterNode doesn't carry any data type information.

      Ugly workaround, forcing creation of LiteralNode:

      Root<User> u = criteria.from(User.class);
      criteria.multiselect(
          u.get("username"),
          cb.selectCase()
              .when(
                  cb.equal(
                      cb.length(u.get("homeAddress").<String>get("zipcode")), 5
                  ), 1
              )
              .when(
                  cb.equal(
                      cb.length(u.get("homeAddress").<String>get("zipcode")), 4
                  ), 2
              )
              .otherwise(3)
      );
      

        Attachments

          Activity

            People

            • Votes:
              6 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: