web-dev-qa-db-fra.com

Comment utiliser un paramètre dynamique dans une clause IN d'une requête nommée JPA?

mon problème concerne ce type de requête:

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

le code précédent fonctionne bien dans Sql Developer . La même requête statique fonctionne aussi bien et me renvoie quelques résultats;

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

Mais lorsque j'essaie de paramétrer cela, je rencontre un problème.

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();

Je n'ai aucun résultat (mais pas d'erreur dans la console). Et quand je regarde le journal, je vois une chose pareille:

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

J'ai aussi essayé de ne pas utiliser de guillemets (avec un résultat similaire), ni de paramètre non ordonné (: selectedValues), ce qui conduit à une telle erreur:

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

J'ai finalement essayé de placer les parenthèses directement dans le paramètre, au lieu de la requête, mais cela ne fonctionnait pas non plus ...

Je pouvais construire ma requête au moment de l'exécution, pour correspondre au premier cas (de travail), mais je préférerais le faire de la bonne manière; ainsi, si quelqu'un a une idée, je le lirai avec un grand intérêt!

FYI: JPA version 1.0Oracle 11G

13
Marvin

JPA prend en charge l'utilisation d'une collection en tant que paramètre littéral de liste uniquement dans les requêtes JPQL, et non dans les requêtes natives. Certains fournisseurs JPA la prennent en charge en tant que fonctionnalité exclusive, mais cela ne fait pas partie des spécifications JPA (voir https://stackoverflow.com/a/3145275/1285097 ).

Les paramètres nommés dans les requêtes natives ne font pas non plus partie de la spécification JPA. Leur comportement dépend du fournisseur de persistance et/ou du pilote JDBC.

Hibernate avec le pilote JDBC pour Oracle prend en charge ces deux fonctionnalités.

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();
32
Marc-André

Au lieu de:

nativeQuery.setParameter("selectedValues", params);

Je devais utiliser:

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

Remplacez ceci:

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

avec

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

J'ai aussi fait face au même problème.
C'est ce que j'ai fait:

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

Et maintenant, vous pouvez définir l’échantillon dans params.

0
Anand

Cela a fonctionné pour moi dans le derby. paramètre sans "()".

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