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

Use JDBC bind variables for handling JPA Criteria query numeric literals

    Details

      Description

      A predicate with a String literal criteriaBuilder.equal(from.get("name"), "horse"); creates a bind parameter: name=:param. Fine!

      A predicate with a numeric literal criteriaBuilder.equal(from.get("age"), Integer.valueOf(42)); does not create a bind parameter: age=42. Not fine!

      The concern here is that the fact that literals are used in the JDBC query rather than bind variables (parameters) a PreparedStatement cannot be effectively cached.

      I think HHH-4698 Closed caused this issue.

      Test Case

      Animal.java
      @Entity
      public class Animal {
        @Id
        Long id;
        String name;
        Integer age;
      }
      
      CriteriaParameterTest.java
      @Entity
        @Test
        public void testPredicateWithString() {
          EntityManager entityManager = getEntityManager();
      
          CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
          CriteriaQuery<Animal> criteriaQuery = criteriaBuilder.createQuery(Animal.class);
          Root<Animal> from = criteriaQuery.from(Animal.class);
      
          Predicate namePredicate = criteriaBuilder.equal(from.get("name"), "horse");
      
          criteriaQuery.select(from).where(namePredicate);
          TypedQuery<Animal> typedQuery = entityManager.createQuery(criteriaQuery);
      
          Query query = typedQuery.unwrap(QueryImpl.class).getHibernateQuery();
          System.out.println(query.getQueryString());
          assertTrue(query.getQueryString().contains("name=:param"));
        }
      
        @Test
        public void testPredicateWithInteger() {
          EntityManager entityManager = getEntityManager();
      
          CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
          CriteriaQuery<Animal> criteriaQuery = criteriaBuilder.createQuery(Animal.class);
          Root<Animal> from = criteriaQuery.from(Animal.class);
      
          Predicate agePredicate = criteriaBuilder.equal(from.get("age"), Integer.valueOf(42));
      
          criteriaQuery.select(from).where(agePredicate);
          TypedQuery<Animal> typedQuery = entityManager.createQuery(criteriaQuery);
      
          Query query = typedQuery.unwrap(QueryImpl.class).getHibernateQuery();
          System.out.println(query.getQueryString());
          assertTrue(query.getQueryString().contains("age=:param"));
        }
      }
      

        Attachments

          Issue links

            Activity

              People

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

                Dates

                • Created:
                  Updated:
                  Resolved: