2016-09-26 20 views
0

Paramertizedネイティブクエリ[カンマ区切りの文字列としてパラメータ](JPAを使用して)

Orm.xml 
    <named-native-query name="getAgencyUsersByRoles"> 
     <query><![CDATA[SELECT DISTINCT a1.USR_LOGIN,c.PERSON_FIRST_NAME,c.PERSON_LAST_NAME,a1.EMAIL, b.auth_role_code FROM USERS a1,PERSON_AUTH_ROLES b,PERSON c WHERE ((b.group_code = 'RCATAG' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN (?)) OR (b.group_code = 'RCEMP' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN (?))) AND a1.email IS NOT NULL AND a1.status in ('ACTIVE','PASSWORD EXPIRED') ORDER BY a1.usr_login]]></query> 
    </named-native-query> 

orm.xmlで私のネイティブクエリを定義していますjpaを使用してクエリを実行している場所のコード。

Query query = getEntityManager() 
      .createNamedQuery(NotificationPersistenceConstants.GET_AGENCY_USERS_BY_ROLES); 
    query.setParameter(1, roles); 
    query.setParameter(2, cccRoles); 
    // fetch the results 
    List<Object[]> list = query.getResultList(); 

は、このクエリは、私は私のappplicationのJPAのログを確認し、実行しながら、任意の例外がスローされますが、私は空の結果を返していません。

DBサーバーで同じクエリを実行すると、クエリに問題がないことを証明する結果セットが得られます。テーブルには、このクエリに対するレコードが返されます。

私は自分のネイティブクエリを壊して、クエリ内にあるすべてのテーブルに対して別々のネイティブクエリとしてそれらを実行しようとしました。 以下は、DISTINCTキーワードが原因である可能性があるかどうかを確認するためにDISTINCT句で試したことです。しかし、彼らはすべての良い仕事をし、私は、クエリに渡していた役割& cccRolesのクエリーパラメータを更新しましたList<Object[]>

SELECT DISTINCT a1.USR_LOGIN FROM USERS a1 ORDER BY a1.usr_login 
SELECT DISTINCT b.auth_role_code FROM PERSON_AUTH_ROLES b 
SELECT DISTINCT c.PERSON_LAST_NAME FROM PERSON c 

の下で結果を与えました。

roles = 'teller','lender','bacth',etc... // This list is dynamically created at runtime 
cccRoles = 'cccadmin','ccuser',etc // This list is dynamically created at runtime 

ここでは何が問題なのかよくわかりません。

クエリ? - 私はDBサーバーで直接同じクエリを実行し、良い仕事を確認したとしてはいけません。

EntityManager(JPA)? - すべての設定を検証し、前述の個々のクエリを実行し、結果を戻しました。誰もが8.5、JPA 2.0 WAS使用して、同じ問題に遭遇した場合

は?参加...私を助けて

してください。

+0

クエリをトレースしてみます。例: 'セッションセットイベントを変更する '10046トレース名コンテキストを永遠に、レベル12';' –

答えて

1

私は問題にドリルダウンすることができました。問題は、クエリオブジェクトを設定していたパラメータであることがわかりました。コードの

犯人ライン:

String roles = 'teller','lender','bacth';// This list is dynamically created at runtime of nth elements 
Strign cccRoles = 'cccadmin','ccuser';// This list is dynamically created at runtime of nth elements 
Query query = getEntityManager().createNamedQuery(NotificationPersistenceConstants.GET_AGENCY_USERS_BY_ROLES); 
query.setParameter(1,roles); 
query.setParameter(1,cccRoles); 

ここに私の上記のコードでroles & cccRoles文字列は、単一のに対して置換なっていますか?クエリ文字列のプレースホルダが見つかったときに、文字列全体(つまり 'teller'、 'lender'、 'bacth')がdbの各dbレコードに対しての列と照合され、それに対するいかなる記録も見つけられなかった。

一方、私は、クエリで直接この文字列パラメータ(roles & cccRoles)を代入することにより、Javaで同じクエリ文字列を構築し、createNativeQuery(コールした場合)、それはのようなものを作品:

Query query = getEntityManager().createNativeQuery("SELECT DISTINCT a1.USR_LOGIN,c.PERSON_FIRST_NAME,c.PERSON_LAST_NAME,a1.EMAIL, b.auth_role_code FROM USERS a1,PERSON_AUTH_ROLES b,PERSON c WHERE ((b.group_code = 'RCATAG' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN ('teller','lender','bacth')) OR (b.group_code = 'RCEMP' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN ('cccadmin','ccuser'))) AND a1.email IS NOT NULL AND a1.status in ('ACTIVE','PASSWORD EXPIRED') ORDER BY a1.usr_login"); 

Bottomline?(placeholder)のサブパーティションがsetParameterのオブジェクトを使用してSQLクエリで発生するたびに、渡されたパラメータ文字列がコンマで区切られていても、単一の列値としてマップされます。

しかし、(setParameterを使用せずに)パラメータ文字列を直接連結してjavaで同じクエリを構築し、それを実行すると、それは動作し、検索する文字列のリストとみなされます。このような状況に

考えられる解決策:

  • 交換して、文字列のparamsの全てのこのような動的なリストを連結し、完全なクエリを作成(setParameter()を使用せずに)ANS使用して、createNativeQuery()
  • 基準BuilderのAPIを使用して実行します。クエリーを作成して実行してください。 (推奨)
  • ビルド必要な番号。 ?(placeholders)をListのサイズに基づいて作成し、同等の番号を呼び出します。ループ内のsetParametersの

  • ?? (誰もがこのような状況のplzのヘルプに他のよりよい解決策を持っています。)

私はまだJavaで実行時に同じクエリ文字列を構築したときに対createNativeQueryを呼び出すの違いは何であるかにような答えを取得しようとしているが、 query.setParameter()を使用してクエリパラメータを設定します。

0

これはおそらく、連結されたパラメータ'teller','lender','bacth'を1つのパラメータに渡しているため、jpaの単一の文字列のパラメータとして比較される可能性があります。 したがって、結果は返されません。

関連する問題