在JPQL中可以选择EXISTS()吗?

时间:2011-07-24 00:01:40

标签: java-ee jpa jpa-2.0 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中使用类似的查询时,我得到错误:

  

“意外结束子树”

根据我的理解意味着查询中缺少某些内容。有没有人知道如何解决它?

6 个答案:

答案 0 :(得分:8)

您可以使用case expression进行布尔查询。

从JPA 2.0(Java EE 6)开始,您可以create a 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();

答案 1 :(得分:6)

不,这是不可能的。

请参阅oracle的JPQL BNF文档。

  

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] EXISTS(子查询)

答案 2 :(得分:1)

您的括号不匹配。尝试删除not之前的那个(以及第一个存在的那个):

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

exists()

周围不需要括号

答案 3 :(得分:1)

或者,您可以使用select count(...)并测试它是否返回0。这应该几乎同样有效,而不需要编写更多代码(事实上,查询本身可能看起来更简单)。

答案 4 :(得分:1)

在使用

的项目中
    <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作为持久性提供程序,我想我可以在这里添加它。

答案 5 :(得分:1)

DB不计算所有记录的效率更高。创建本机查询

弹簧数据JPA

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

或JPA:

@NamedNativeQuery(name=.., query="..", resultClass=..)