いくつかの条件が真であるかどうかをチェックし、出力として単純なブール結果を返すクエリを実行しようとしています。少し注意が必要なのは、条件の1つが、一連の基準に対して結果が返されないかどうかをテストすることです。
現在、MySQLに裏打ちされた、プロバイダーとしてhibernateを使用したJPA-2.0を使用しています。 MySQLで正常に機能するサンプルクエリを取得しましたが、JPQLで実行しようとすると失敗します。 MySQLクエリは次のようになります。
Select exists(Select statement with criteria)
or not exists(Select statement with criteria);
CASEを使用しても同じ出力が得られましたが、JPQLはそのステートメントをサポートしていないためです。
とにかく、JPQLで同様のクエリを使用しようとすると、エラーが発生します。
「予期しないサブツリーの終わり」
これは私の理解から、クエリに何かが欠けていることを意味します。誰かがそれを修正する方法を知っていますか?
この回答は廃止されました。正しい答えを参照してください Rene Link
いいえ、できません。
Oracleの JPQL BNF ドキュメントを参照してください。
simple_cond_expression:: =比較式| between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression | exists_expression
exists_expression:: = [NOT] EXISTS(subquery)
case式 を使用してブールクエリを実行できます。
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();
または、select count(...)
を使用して、0
が返されるかどうかをテストすることもできます。これは、はるかに多くのコードを記述することなく、ほぼ同じくらい効率的です(実際、クエリ自体はおそらくより単純に見えるでしょう)。
ブラケットが一致していません。 not
の前の1つを削除してみてください(そして、最初の周りのものが存在します)。
_select exists(Select statement with criteria)
or not exists(Select statement with criteria);
_
exists()
の前後に括弧は必要ありません
を使用するプロジェクトで
<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=?
DBがすべてのレコードをカウントしない方が効率的です。ネイティブクエリを作成する
Spring-Data-JPA
@Query(value = ".....", nativeQuery = true)
またはJPA:
@NamedNativeQuery(name=.., query="..", resultClass=..)