2012-04-30 5 views
3

このJPA QLを条件ビルダに変換しようとしています。 JBoss 6.0。CriteriaBuilderを使用しているときにコンパイルエラー

"SELECT ba FROM BankAccount ba WHERE ba.balance >= :amt ORDER BY ba.ownerName ASC" 

私はいくつかのチュートリアルに従ってこのコードを書いています。

public List<BankAccount> findWithBalance(int amount) { 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class); 
    Root<BankAccount> from = cq.from(BankAccount.class); 

    ParameterExpression<Integer> balance = cb.parameter(Integer.class); 
    cq.select(from); 

    Predicate predicate = cb.gt(from.get("balance"), balance); 
    cq.where(predicate); 

    cq.orderBy(cb.asc(from.get("ownerName"))); 

    TypedQuery<BankAccount> query = em.createQuery(cq); 

    return query.getResultList(); 
} 

しかし、私はラインでのコンパイルエラーを取得しています:

Predicate predicate = cb.gt(from.get("balance"), balance); 

エラーは次のとおりです。

The method gt(Expression<? extends Number>, Expression<? extends Number>) in the type CriteriaBuilder is not applicable for the arguments (Path<Object>, ParameterExpression<Integer>) 

答えて

10

まあ、最終的にgt()メソッドを呼び出す正しい方法が見つかりました。ここに完全な解決策があります。 JBoss 6で完全にテストされました。

public List<BankAccount> findWithBalance(int amount) { 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class); 
    Root<BankAccount> from = cq.from(BankAccount.class); 

    ParameterExpression<Integer> balance = cb.parameter(Integer.class); 
    cq.select(from); 

    //Here is the trick! 
    Predicate predicate = cb.gt(from.<Integer> get("balance"), balance); 

    cq.where(predicate); 
    cq.orderBy(cb.asc(from.get("ownerName"))); 

    TypedQuery<BankAccount> query = em.createQuery(cq); 

    query.setParameter(balance, amount); 

    return query.getResultList(); 
} 
0

amountint、ないExpressionであるため、コンパイラは不平を言っていますあなたが定数であり、それを使用して、良いものになるようにExpressionを構築する方法を見つけ出すことができるかどうかを見てください。

+0

あなたは、改訂コードであなたの投稿を編集して、現在取得中のエラーメッセージを表示できますか? ParameterExpressionであるargを使用している場合、同じエラーが発生しているとは想像もできません。また、それはおそらくあなたが望むものではありません。 –

+0

コードと新しいエラーメッセージが更新されました。私がやっていることは、さまざまなチュートリアルからまっすぐです。私は基準のクエリがJBoss 6でできるとは思わない。 – RajV

3

JPAの型安全性機能は、互換性のない型でこのような比較を制限するため、コンパイラ自体がエラーを発生させます。

ここでfrom.get("balance")Path<Object>を返しますが、このメソッドはjava.lang.Number型のパラメータを受け入れることができるため、エラーになります。

以下のコードを試すことができます。あなたはメタモデルのAPIを使用している場合

//-- 
    Metamodel metamodel = em.getMetamodel(); 
    EntityType<BankAccount> pClass = metamodel.entity(BankAccount.class); 
    Predicate predicate = cb.gt(from.get(pClass.getSingularAttribute("balance", Integer.class)), balance); 
//-- 

、あなたはデバッグに&非常にきれいに簡単であるcb.gt(from.get(BankAccount_.balance), balance)としてClassName_.fieldを指定することで直接retieveことができます。

しかし、多くのエンティティがある場合、JPAプロバイダがメタモデルを生成しない場合は、手動でMetamodelクラスを作成するのが難しい場合があります。

+0

私はその変更を行った。新しいエラーは次のとおりです。 CriteriaBuilderタイプのgt(Expression <?extends Number>、Expression <?extends Number>)メソッドは、引数には使用できません(SingularAttribute 、ParameterExpression ) – RajV

+0

@RajVコンパイルエラーを削除するように編集しましたが、テストできません。 –

+0

私は自分の答えを掲載しました。上記をご覧ください。 – RajV

関連する問題