web-dev-qa-db-ja.com

JPA名前付きクエリのIN句で動的パラメータを使用する方法

私の問題はこの種のクエリについてです:

select * from SOMETABLE where SOMEFIELD in ('STRING1','STRING2');

前のコードはSql Developer内で正常に機能します。同じ静的クエリも正常に機能し、いくつかの結果を返します。

Query nativeQuery = em.createNativeQuery(thePreviousQuery,new someResultSet());
return nativeQuery.getResultList();

しかし、これをパラメーター化しようとすると、問題が発生します。

final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (?selectedValues)";
Query nativeQuery = em.createNativeQuery(parameterizedQuery ,new someResultSet());
nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");
return nativeQuery.getResultList();

結果は得られませんでした(コンソールにエラーはありません)。ログを見ると、次のようなことがわかります。

select * from SOMETABLE where SOMEFIELD in (?)
bind => [STRING1,STRING2]

また、引用符を使用せず(同様の結果が得られる)、または順序付けられていないパラメーター(:selectedValues)を使用しようとしましたが、このようなエラーが発生します。

SQL Error: Missing IN or OUT parameter at index:: 1

私は、クエリではなく、パラメータに括弧を直接設定しようと試みましたが、これも機能しませんでした...

最初の(動作中の)ケースに一致するように、実行時にクエリを作成できますが、適切な方法でそれを行います。したがって、誰かがアイデアを持っている場合、私はそれらを非常に興味を持って読みます!

参考:JPAバージョン1.0 Oracle 11G

15
Marvin

JPAは、ネイティブクエリではなく、JPQLクエリでのみリストリテラルパラメータとしてコレクションの使用をサポートします。一部のJPAプロバイダーは独自の機能としてサポートしていますが、JPA仕様の一部ではありません( https://stackoverflow.com/a/3145275/1285097 を参照)。

ネイティブクエリの名前付きパラメータもJPA仕様の一部ではありません。それらの動作は、永続性プロバイダーやJDBCドライバーに依存します。

Oracle用のJDBCドライバーを備えたHibernateは、これらの機能の両方をサポートします。

List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in (:selectedValues)";
return em.createNativeQuery(parameterizedQuery)
         .setParameter("selectedValues", selectedValues)
         .getResultList();
37
Marc-André

の代わりに:

nativeQuery.setParameter("selectedValues", params);

私は使用しなければなりませんでした:

nativeQuery.setParameterList("selectedValues", params);
2
Brian

これを置き換えます:

nativeQuery.setParameter("selectedValues","'STRING1','STRING2'");

List<String> params;
nativeQuery.setParameter("selectedValues",params);
1
Sabuj Hassan

私も同じ問題に直面しました。
これが私がしたことです。

List<String> sample = new ArrayList<String>();
sample.add("sample1");
sample.add("sample2");

これで、paramsにサンプルを設定できます。

0
Anand

これはダービーで私のために働いた。 「()」なしのパラメータ。

List<String> selectedValues = Arrays.asList("STRING1", "STRING2");
final String parameterizedQuery = "select * from SOMETABLE where SOMEFIELD in 
:selectedValues";
return em.createNativeQuery(parameterizedQuery)
         .setParameter("selectedValues", selectedValues)
         .getResultList();
0
Pradeep