Возможен ли выбор EXISTS () в JPQL? - PullRequest
16 голосов
/ 24 июля 2011

Я пытаюсь выполнить запрос, который проверяет, выполняются ли некоторые условия, и возвращает простой логический результат в качестве вывода. Что делает его немного сложным, так это то, что одним из условий является проверка того, не возвращаются ли результаты для набора критериев.

В настоящее время я использую JPA-2.0 с Hibernate в качестве моего провайдера при поддержке MySQL. Я получил пример запроса, работающего нормально в MySQL, но при попытке запустить его в JPQL он проваливается. Запрос MySQL выглядит примерно так:

Select exists(Select statement with criteria) 
  or not exists(Select statement with criteria);

Я также получил тот же вывод, используя CASE, но JPQL не поддерживает этот оператор.

В любом случае, когда я пытаюсь использовать аналогичный запрос в JPQL, я получаю ошибку:

"неожиданный конец поддерева"

что, насколько я понимаю, означает, что в запросе чего-то не хватает. У кого-нибудь есть идеи как это исправить?

Ответы [ 7 ]

9 голосов
/ 15 июня 2015

Вы можете выполнить логический запрос, используя выражение .

Начиная с JPA 2.0 (Java EE 6) вы можете создать TypedQuery .

String query = "select case when (count(*) > 0)  then true else false end from ......"
TypedQuery<Boolean> booleanQuery = entityManager.createQuery(query, Boolean.class);
boolean exists = booleanQuery.getSingleResult();

В JPA 1.0 (Java EE 5) вы должны использовать нетипизированный запрос.

Query booleanQuery = entityManager.createQuery(query);
boolean exists = (Boolean) booleanQuery.getSingleResult();
7 голосов
/ 24 июля 2011

Этот ответ устарел.Пожалуйста, обратитесь к правильному ответу от Rene Link


Нет, это невозможно.

См. JPQL BNF документация от оракула. ​​

simple_cond_expression :: = сравнение_экспрессия |Между выражением |like_expression |in_expression |null_comparison_expression |empty_collection_comparison_expression |collection_member_expression | существует_выражение

существует_выражение :: = [NOT] EXISTS (подзапрос)

1 голос
/ 21 мая 2018

Это более эффективно для БД, не считая все записи.Создать собственный запрос

Spring-Data-JPA

@Query(value = ".....", nativeQuery = true)

или JPA:

@NamedNativeQuery(name=.., query="..", resultClass=..)
1 голос
/ 24 февраля 2017

В проекте, который использует

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.2.4.Final</version>
    </dependency>
    ...

Я успешно использовал

exists(select s.primaryKey from Something s)

пункт. Так что это могло измениться. Это также может быть Hibernate-проприетарный. Поскольку многие люди используют Hibernate в качестве поставщика постоянных данных, я подумал, что мог бы добавить это сюда.

1 голос
/ 01 марта 2012

В качестве альтернативы вы можете использовать select count(...) и проверить, возвращает ли он 0.Это должно быть почти так же эффективно, без необходимости писать намного больше кода (фактически, сам запрос, вероятно, будет выглядеть проще).

1 голос
/ 24 июля 2011

У вас несоответствующие скобки. Попробуйте удалить один до not (а те, что вокруг первого, существуют):

select exists(Select statement with criteria) 
  or not exists(Select statement with criteria);

Вам не нужны скобки вокруг exists()

0 голосов
/ 13 мая 2018

В проекте с Hibernate 5.2 (который поддерживает JPA 2.1) и Spring Data Jpa 2.0.6 я успешно использовал этот запрос JPQL:

@Query("SELECT COUNT(c) > 0 FROM Contract c WHERE c.person.id = :pid")
Boolean existContractForPerson(@Param("pid") Long personId);

В журналах я прочитал, что получен нативныйзапрос следующий:

select count(contract0_.contract_id)>0 as col_0_0_ from contracts contract0_ where contract0_.fk_person_id=?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...