Использование JPA 2.0 Criteria API и приведение приводят к сбою сгенерированного JPQL в Hibernate - PullRequest
7 голосов
/ 24 ноября 2010

Я впервые пользуюсь новым API-критерием JPA 2.0 и столкнулся с проблемой, когда мне нужно привести числовое поле к String, чтобы сравнить его с параметром String. Причина в том, что я хочу искать частичные числа, поэтому я использую «лайк» в CriteriaBuilder. Вот пример кода:

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 в выражение, необходимое для метода like в 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)

Спасибо

Ответы [ 2 ]

4 голосов
/ 20 июля 2012

Что касается JPA, метод Expression.as используется для решения неправильных задач. Приведение Expression<Number> к Expression<String> не должно работать через Expression.as . Конечно, было бы неплохо иметь четкое сообщение об ошибке вместо некорректного JPQL.

Как сказано в документации, он выполняет приведение типов, что отличается от преобразования типа в другое:

Выполнить приведение типа к выражению, возвращая новое выражение объект. Этот метод не вызывает преобразование типов: тип времени выполнения не изменился. Предупреждение: может привести к сбою во время выполнения.

3 голосов
/ 27 ноября 2010

Как отметил axtavt в комментариях к вопросу, это ошибка в Hibernate 3.6 http://opensource.atlassian.com/projects/hibernate/browse/HHH-5755

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...