Note: I have a reproducible test case available in 5.x; the same test case succeeds in 6.x. It appears that you can’t reuse a criteria Expression - perhaps Hibernate is mutating them when it builds the query? Example:
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<Employee> employee = query.from(Employee.class);
final Expression<Boolean> hasManager = cb.isNotNull(employee.get(Employee_.manager));
final Expression<Integer> numWithManager = cb.sum(
cb.<Boolean, Integer>selectCase(cb.isTrue(hasManager))
.when(true, 1)
.otherwise(0));
final Expression<Integer> numWithoutManager = cb.sum(
cb.<Boolean, Integer>selectCase(cb.isFalse(hasManager))
.when(true, 1)
.otherwise(0));
query.select(cb.array(numWithManager, numWithoutManager));
entityManager.createQuery(query).getResultStream().forEach(x -> System.out.println("RESULT: [" + x[0] + "," + x[1] + "]"));
entityManager.getTransaction().commit();
entityManager.close();
Running this code results in this exception:
Note that the two generated case…when expressions are the same, whereas in the Java code they are supposed to be the opposite of each other. This is what makes me think the bug is triggered by the reuse of final Expression<Boolean> hasManager in the Java code - which could only matter if Hibernate is mutating the expression or whatever. AFAIK there is no restriction in the Criteria API that says you can’t use an Expression more than once… ? |