web-dev-qa-db-ja.com

IN式のリストとしてのパラメーターの設定

リストをIN式で使用するためのパラメーターとして設定しようとすると、Illegal引数例外が発生します。インターネット上のさまざまな投稿は、これが可能であることを示しているようですが、確かに私にとってはうまくいきません。 ToplinkでGlassfish V2.1を使用しています。

他の誰かがこれを機能させることができましたか?

ここにいくつかのコード例があります:

List<String> logins = em.createQuery("SELECT a.accountManager.loginName " +
    "FROM Account a " +
    "WHERE a.id IN (:ids)")
    .setParameter("ids",Arrays.asList(new Long(1000100), new Long(1000110)))
    .getResultList();

スタックトレースの関連部分:

 Java.lang.IllegalArgumentException:クエリ文字列SELECT a.accountManager.loginNameから、クラスJava.lang.Longの予期されるタイプで、パラメーターaccountIdsにタイプJava.util.Arrays $ ArrayListの値を設定しようとしましたFROMアカウントa WHERE a.id IN(:accountIds)。
 at Oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.setParameterInternal(EJBQueryImpl.Java:663)
 at Oracle .toplink.essentials.internal.ejb.cmp3.EJBQueryImpl.setParameter(EJBQueryImpl.Java:202)
 at com.corenap.newtDAO.ContactDaoBean.getNotificationAddresses(ContactDaoBean.Java:437)
 at日曜日.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
 at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25) 
 at Java.lang.reflect.Method.invoke(Method.Java:597)
 at com.Sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurity Manager.Java:1011)
 at com.Sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.Java:175)
 at com.Sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer。 Java:2920)
 at com.Sun.ejb.containers.BaseContainer.intercept(BaseContainer.Java:4011)
 at com.Sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.Java: 203)
 ... 67以上
24
perilandmishap

JPQLが無効です。括弧を削除してください

List<String> logins = em.createQuery("SELECT a.accountManager.loginName " +
    "FROM Account a " +
    "WHERE a.id IN :ids")
    .setParameter("ids",Arrays.asList(new Long(1000100), new Long(1000110)))
    .getResultList();
39
James

答えを見つけました。パラメーターとしてリストを提供することは、JPA 1.0ではサポートされていません。ただし、JPA 2.0ではサポートされています。

Glassfish v2.1のデフォルトの永続化プロバイダーは、JPA 1.0を実装するToplinkです。JPA2.0を取得するには、Glassfish v3プレビューのデフォルトであるEclipseLinkが必要であるか、v2.1にプラグインできます。

-ローレン

20
perilandmishap

これが誰かを助けることを願っています。私は問題に直面し、解決するために次のことを行いました(eclipselink 2.2.0を使用)

  1. クラスパスにJavaEE jarとjpa 2 jar(javax.persistence * 2 *)がありました。クラスパスからJavaEEを削除しました。

  2. 例外をスローしていた" idItm IN ( :itemIds ) "のようなものを使用していました:

クエリ文字列からのクラスJava.lang.Stringの予想されるタイプを持つパラメータitemIdsのタイプクラスJava.util.ArrayList

解決策:in条件を" idItm IN :itemIds "に変更しました。つまり、角かっこ()を削除しました。

10
dillip

簡単に言うと、パラメーターはListになり、次のように設定されます

"...WHERE a.id IN (:ids)")
.setParameter("ids", yourlist)

これはJPA 1.0で機能します

3

IN(:ids)の代わりにIN:ids-動作します。

0
Atul Jain

そして、何らかの理由でEclipseLinkを使用できない場合は、クエリに必要なビットを追加するために使用できるメソッドを次に示します。結果の文字列をクエリに挿入して、「a.id IN(:ids)」を挿入します。



     /** 
     /* @param field The jpql notation for the field you want to evaluate
     /* @param collection The collection of objects you want to test against
     /* @return Jpql that can be concatenated into a query to test if a feild is in a 
     */
collection of objects
    public String in(String field, List collection) {
        String queryString = new String();
        queryString = queryString.concat(" AND (");
        int size = collection.size();
        for(int i = 0; i > size; i++) {
            queryString = queryString.concat(" "+field+" = '"+collection.get(i)+"'");
            if(i > size-1) {
                queryString = queryString.concat(" OR");
            }
        }
        queryString = queryString.concat(" )");
        return queryString;
    }
0
perilandmishap

代わりにNamedQueryを使用します。

List<String> logins = em.createNamedQuery("Account.findByIdList").setParameter("ids", Arrays.asList(new Long(1000100), new Long(1000110))).getResultList();

名前付きクエリをエンティティに追加する

@NamedQuery(name = "Account.findByIdList", query = "SELECT a.accountManager.loginName FROM Account a WHERE a.id IN :ids")
0
toquart