如何在JPA命名查询的IN子句中使用动态参数?

时间:2014-01-31 15:49:32

标签: sql oracle jpa oracle11g

我的问题是关于这种查询:

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

5 个答案:

答案 0 :(得分:36)

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

答案 1 :(得分:2)

而不是:

nativeQuery.setParameter("selectedValues", params);

我不得不使用:

nativeQuery.setParameterList("selectedValues", params);

答案 2 :(得分:1)

替换它:

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

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

答案 3 :(得分:0)

这对德比有用。参数没有“()”。

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

答案 4 :(得分:0)

我也遇到了同样的问题。
这就是我所做的:

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

现在您可以在params中设置样本了。