Note: I have a reproducible test case available in 5.x; the same test case succeeds in 6.x . :
[https://github.com/archiecobbs/hibernate-test-case-templates/tree/HHH-16852|https://github.com/archiecobbs/hibernate-test-case-templates/tree/HHH-16852]
It appears that you can’t reuse a criteria {{Expression}} - perhaps Hibernate is mutating them when it builds the query?
Example:
{code:java} 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();{code}
Running this code results in this exception:
{noformat}java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: is near line 1, column 41 [select sum(case generatedAlias0.manager is not null when true then 1 else 0 end), sum(case generatedAlias0.manager is not null when true then 1 else 0 end) from org.hibernate.bugs.Employee as generatedAlias0] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:757) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:811) at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:314) at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:170) at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:774) at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23) at org.hibernate.bugs.JPAUnitTestCase.hhh123Test(JPAUnitTestCase.java:61){noformat}
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… ? |
|