使用 JPA 2.0 Criteria API 和强制转换会导致生成的 JPQL 在 Hibernate 中失败
我是新 JPA 2.0 Criteria API 的首次用户,当我需要将数字字段转换为字符串以将其与字符串参数进行比较时,我遇到了问题。原因是我想搜索部分数字,因此我在 CriteriaBuilder 上使用“like”。下面是一个代码示例:
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);
}
}
重要的部分是
Predicate parcelNumberIdPredicate = cb.like(
parcelDO.<Long> get("parcelNumberId").as(String.class),
parcelNumberId + "%");
我使用 Criteria API 将 Path 转换为 CriteriaBuilder 上类似方法所需的表达式。
现在,当我运行并执行此代码时,底层 JPA 2.0 实现 Hibernate 会失败,并出现以下异常:
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]
在我看来,Hibernate 正在生成不正确的 JPQL。
我不知道出了什么问题,你能帮忙吗?
我使用最新的Hibernate版本(3.6.0.CR2)
谢谢
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.<Long> 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于 JPA 来说,Expression.as 方法被用于达到错误的目的。将
Expression
转换为Expression
不应该通过 Expression.as。当然,如果有清晰的错误消息而不是不正确的 JPQL,那就太好了。正如文档中所述,它执行类型转换,这与从类型到其他类型的转换是不同的概念:
What it comes to JPA, Expression.as method is used to serve wrong purpose in question. Casting
Expression<Number>
toExpression<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:
正如 axtavt 在问题的评论中所述,这是 Hibernate 3.6 http: //opensource.atlassian.com/projects/hibernate/browse/HHH-5755
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