7

我是新 JPA 2.0 Criteria API 的第一次用户,当我需要将数字字段转换为 String 以将其与 String 参数进行比较时,我遇到了问题。原因是我想搜索部分数字,所以我在 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)

谢谢

4

2 回答 2

4

谈到 JPA,Expression.as 方法被用于服务于有问题的错误目的。Casting Expression<Number>toExpression<String>不应该通过Expression.as工作。当然,最好有清晰的错误消息而不是不正确的 JPQL。

如文档中所述,它执行类型转换,这与从类型到其他类型的转换是不同的概念:

对表达式执行类型转换,返回一个新的表达式对象。此方法不会导致类型转换:运行时类型不会更改。警告:可能会导致运行时失败。

于 2012-07-20T12:15:01.090 回答
3

正如问题评论中的axtavt所述,这是Hibernate 3.6 http://opensource.atlassian.com/projects/hibernate/browse/HHH-5755中的一个错误

于 2010-11-26T23:59:20.047 回答