Using JPA 2.0 Criteria API and cast causes generated JPQL to fail in Hibernate
I am a first time user of the new JPA 2.0 Criteria API and I 'm running into a problem when I need to cast a number field to String to compare it with a String parameter. Reason is that I want to search for partial numbers, so I use a 'like' on the CriteriaBuilder. Here's a code sample:
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<ParcelDO> cq = cb.createQuery(ParcelDO.class);
Root<ParcelDO> parcelDO = cq.from(ParcelDO.class);
cq.select(parcelDO);
String parcelNumberId = parcelSearchDetailDO.getParcelNumberId();
if (parcelNumberId != null && !parcelNumberId.isEmpty()) {
Predicate parcelNumberIdPredicate = cb.like(
parcelDO.<Long> get("parcelNumberId").as(String.class),
parcelNumberId + "%");
if (cq.getRestriction() != null) {
cq.where(cq.getRestriction(), parcelNumberIdPredicate);
} else {
cq.where(parcelNumberIdPredicate);
}
}
The important part is
Predicate parcelNumberIdPredicate = cb.like(
parcelDO.<L开发者_如何学Pythonong> get("parcelNumberId").as(String.class),
parcelNumberId + "%");
where I use the Criteria API to convert the Path into a Expression needed for the like method on the CriteriaBuilder.
Now when I run and it executes this code, the underlying JPA 2.0 implementation Hibernate fails with the following exception:
Caused by: org.hibernate.hql.ast.QuerySyntaxException:
expecting CLOSE, found '(' near line 1, column 117
[select generatedAlias0 from domain.ParcelDO as generatedAlias0 where
cast(generatedAlias0.parcelNumberId as varchar2(255 char)) like :param0]
Looks to me like Hibernate is generating a JPQL that is not correct.
I have no idea what is wrong, can you help?
I use the latest Hibernate version (3.6.0.CR2)
Thank you
What it comes to JPA, Expression.as method is used to serve wrong purpose in question. Casting Expression<Number>
to Expression<String>
is not supposed to work via Expression.as. Of course it would be nice to have clear error message instead of incorrect JPQL.
As said in documentation, it performs typecast, which is different concept than conversion from type to other:
Perform a typecast upon the expression, returning a new expression object. This method does not cause type conversion: the runtime type is not changed. Warning: may result in a runtime failure.
As axtavt stated in the comments in the question, it is a bug in Hibernate 3.6 http://opensource.atlassian.com/projects/hibernate/browse/HHH-5755
精彩评论