2011-07-24 14 views
11

私はいくつかの条件が真であるかどうかをチェックし、出力として単純なブール結果を返すクエリを実行しようとしています。少し難しいのは、一連の条件に対して結果が返されないかどうかをテストすることです。JPQLでEXISTS()を選択できますか?

私は現在、JPA-2.0をMySQLとしてサポートしている私のプロバイダとしてhibernateを使用しています。私はMySQLでうまく動作しているサンプルクエリを得ましたが、JPQLで動作させようとすると、それは破棄されます。 MySQLのクエリは、ビットのようになります。

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

私はまた、CASEを使用して同じ出力を得たが、JPQLは、その文をサポートしていないよう。

"unexpected end of subtree"

私の理解から何かがクエリに欠けていることを意味します。私はJPQLで同様のクエリを使用しようとすると、

はとにかく、私はエラーを取得します。誰にどのようにそれを修正するための任意のアイデアがありますか?

答えて

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(subquery)

1

括弧が揃っていません。 (最初のまわりのものが存在する)not前に1を削除してください:

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

あなたはいいえ、それは不可能であるexists()

+1

これを指摘してくれてありがとうが、括弧で囲まれているかどうかは、依然としてJPQLでは機能しません。 – Elk

+0

はhttp://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/jpa_langref.html#jpa_langref_existsので、マニュアルに従って、少なくとも一部が質問から正しい存在します。 "exists_expression :: = [NOT] EXISTS(サブクエリ)" – Kowser

1

別の方法としては、select count(...)を使用して、それが0を返すかどうかをテストすることができます。これははるかに多くのコードを書くことを必要とせずにほぼ効率的でなければなりません(実際には、クエリ自体はおそらくより単純になります)。

+1

必ずしもそうではありません。おそらく最初の結果が見つかった後に 'exists(...)'が存在するでしょう。 'count(...)'は、実際のカウントを決定するためにさらに多くのインデックス/テーブル行をスキャンする必要があります。 –

+0

@ KonradGarus:とにかくJPQLで動作する唯一の解決策が 'count(..) 'のときは、実際には問題になりません。だから、人生があなたにレモンを与えるとき... –

4

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)では、タイプのないクエリを使用する必要があります。

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

を使用するプロジェクトで

Query booleanQuery = entityManager.createQuery(query); 
boolean exists = (Boolean) booleanQuery.getSingleResult(); 
1

私は正常

exists(select s.primaryKey from Something s) 

句を使用。だから変わったかもしれない。また、Hibernate独自仕様にすることもできます。多くの人が永続化プロバイダとしてHibernateを使用しているので、ここでこれを追加すると思っていました。

関連する問題