Возможен ли Select EXISTS () в JPQL?
Я пытаюсь выполнить запрос, который проверяет, если некоторые условия и возвращает простой логический результат на выходе. Что делает его немного сложным, так это то, что одно из условий-проверить, не возвращаются ли результаты для набора критериев.
в настоящее время я использую 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 ответов
нет, это невозможно.
относятся к JPQL BNF документация от oracle.
simple_cond_expression ::= comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression
exists_expression :: = [NOT] существует (подзапрос)
вы можете сделать логический запрос, используя case expression.
начиная с 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();
у вас есть несоответствие скобок. Попробуйте удалить один перед not
(и те, что вокруг первого существует):
select exists(Select statement with criteria)
or not exists(Select statement with criteria);
вам не нужны скобки exists()
в качестве альтернативы вы можете использовать select count(...)
и проверьте, возвращает ли он 0
. Это должно быть почти так же эффективно, не требуя писать гораздо больше кода (на самом деле сам запрос, вероятно, будет выглядеть проще).
в проекте, который использует
<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 в качестве поставщика сохраняемости, я подумал, что могу добавить это здесь.
в проекте с 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=?
это более эффективно для БД, не считая всех записей. Создать собственный запрос
Весна-данные-JPA
@Query(value = ".....", nativeQuery = true)
или JPA:
@NamedNativeQuery(name=.., query="..", resultClass=..)