When using the CriteriaQuery API and invoking a query using the uniqueResultOptional() methodthrows a QueryException for a Named parameter not set. This exception is not thrown if the JPA method getResultList() is used instead. After debugging this I determined the root cause is the Query returned by Session.createQuery(CriteriaQuery) is a CriteriaQueryTypeQueryAdapter. It overrides the methods for getSingleResult() and getResultList() to invoke the corresponding methods on its jpqlQuery method, a fully populated QueryImpl. Hibernate-specific methods, including uniqueResultOptional() are not overridden by CriteriaQueryTypeQueryAdapter, and thus the corresponding methods are not invoked on the jpqlQuery member. Here is a sample source that causes the problem:
CriteriaQuery<Constraint> constraintQuery =
builder.createQuery( Constraint.class );
Root<Constraint> constraintRoot = constraintQuery.from( Constraint.class );
constraintQuery.select( constraintRoot );
constraintQuery.where( builder.equal( constraintRoot.get( "constraintName" ),
constraint.getConstraintName() ));
Optional<Constraint> dbConstraint = session.createQuery( constraintQuery ).uniqueResultOptional();
And a stack trace snippet illustrating the issue:
Caused by: org.hibernate.QueryException: Named parameter [param0] not set
at org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:234)
at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1283)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1372)
at org.hibernate.query.internal.AbstractProducedQuery.uniqueResult(AbstractProducedQuery.java:1414)
at org.hibernate.query.internal.AbstractProducedQuery.uniqueResultOptional(AbstractProducedQuery.java:1367)
|