Hi all,
Honestly, I'm fairly new with JPA2 Criteria queries - but as far as code effort goes, it has saved me a bit of pain. I'm writing a dynamic query builder (only 1 level deep for basic entities) - but even though I get most queries to work, I am getting the following error. This is using Criteria with a combination of LOWER/UPPER - NOT LIKE:
SELECT COUNT($1.id) FROM User $1 WHERE ($1.owningCompany=:p1) AND LOWER($1.email) NOT LIKE :p2
So in essence, I'm trying to do a count (with a subsequent fetch of a page of 20 results per table view on the UI) where a user belongs to a company, and the lower case email does NOT match the parameter :p2
The bind is as follows:
com.x.y.z.services.helpers.SearchQueryHelper| - Binded search Param: p2 - Value: %will%
The issue I am getting is:
Caused by: com.objectdb.o.UserException: Unexpected query token '$1.email' at com.objectdb.o.MSG.d(MSG.java:61) at com.objectdb.o.TKN.J(TKN.java:755) at com.objectdb.o.TKI.s(TKI.java:229) at com.objectdb.o.QPR.o(QPR.java:158) at com.objectdb.o.QRC.<init>(QRC.java:122) at com.objectdb.o.QRM.US(QRM.java:245) at com.objectdb.o.MST.US(MST.java:884) at com.objectdb.o.WRA.US(WRA.java:286) at com.objectdb.o.WSM.US(WSM.java:113) at com.objectdb.o.STC.r(STC.java:421) at com.objectdb.o.SHN.ah(SHN.java:468) at com.objectdb.o.SHN.J(SHN.java:146) at com.objectdb.o.HND.run(HND.java:133) ... 1 more
So I am definitely saying - maybe my query is stuffed.. which is basically the following (an excerpt of my visitor class for handling String properties in entities):
ParameterExpression<String> stringProp = criteriaBuilder.parameter(String.class); Path<String> path = root.get(property.getFieldName()); Predicate predicate; if(property.getOperator().equals(Operator.LIKE)){ predicate = criteriaBuilder.like(criteriaBuilder.lower(path), stringProp); stringMapOfValues.put(stringProp, property.getWildcardValue()); }else if(property.getOperator().equals(Operator.NOT_LIKE)){ predicate = criteriaBuilder.notLike(criteriaBuilder.lower(path), stringProp); stringMapOfValues.put(stringProp, property.getWildcardValue()); }else if(property.getOperator().equals(Operator.EQUAL)){ predicate = criteriaBuilder.equal(path, stringProp); stringMapOfValues.put(stringProp, property.getValue()); }else if(property.getOperator().equals(Operator.NOT_EQUAL)){ stringMapOfValues.put(stringProp, property.getValue()); predicate = criteriaBuilder.notEqual(path, stringProp); } else{ predicate = criteriaBuilder.isNull(path); } predicatesList.add(criteriaBuilder.and(predicate)); }
The binds are taken care of with the 'mapOfStringValues' later.
Any help is appreciated on this.
Thanks