使用IN的JPA EntityManager createQuery()不起作用

时间:2010-06-24 20:25:26

标签: java hibernate orm jpa

这是失败的:

List<String> names = new ArrayList<String>();
names.add("sold");
Query query = em.createQuery("FROM PropField propField WHERE propField.name IN (?)");
query.setParameter(1, names);
List<PropField> fields = query.getResultList();

这就是:

List<String> names = new ArrayList<String>();
names.add("sold");
Query query = em.createQuery("FROM PropField propField WHERE propField.name IN (?)");
query.setParameter(1, names.toArray());
List<PropField> fields = query.getResultList();

这也是:

List<String> names = new ArrayList<String>();
names.add("sold");
Query query = em.createQuery("FROM PropField propField WHERE propField.name IN ?");
query.setParameter(1, names.toArray());
List<PropField> fields = query.getResultList();

以上的所有其他排列。检查了文档,它说第一个选项应该有效。这是最重要的例外。

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
at org.hibernate.type.StringType.toString(StringType.java:67)

Hibernate的HQL使用setParameterList,但试图在这里坚持使用直接的JPA。

3 个答案:

答案 0 :(得分:20)

从JPA 1.0规范:

  

4.6.4.1位置参数

     

以下规则适用于位置参数。

     
      
  • 输入参数由问号(?)前缀后跟一个整数指定。例如:?1
  •   
  • 输入参数从1开始编号   请注意,在查询字符串中可以多次使用相同的参数,并且查询字符串中参数的使用顺序不必符合位置参数的顺序。
  •   
     

4.6.4.2命名参数

     

命名参数是以“:”符号为前缀的标识符。它遵循第4.4.1节中定义的标识符规则。命名参数区分大小写。

     

示例:

SELECT c
FROM Customer c
WHERE c.status = :stat
     

第3.6.1节描述了用于绑定命名查询参数的API

所以要么使用(使用命名参数):

List<String> names = Arrays.asList("sold");
Query query = em.createQuery("FROM PropField propField WHERE propField.name IN (:names)");
query.setParameter("names", names)
List<PropField> fields = query.getResultList();

或(带位置参数):

List<String> names = Arrays.asList("sold");
Query query = em.createQuery("FROM PropField propField WHERE propField.name IN (?1)");
query.setParameter(1, names)
List<PropField> fields = query.getResultList();

两者都使用Hibernate EM 3.4.0.GA进行了测试。

请注意,强制使用括号括起IN子句的参数是一个错误(至少在JPA 2.0中),如this previous answer中所述。

答案 1 :(得分:1)

我使用带有IN子句的JPA命名查询遇到了与Hibernate类似的问题。我使用了语法:“propField.name IN(?1)”

另见:http://opensource.atlassian.com/projects/hibernate/browse/HHH-4922

http://opensource.atlassian.com/projects/hibernate/browse/HHH-5126

答案 2 :(得分:0)

我无法访问Hibernate环境来试试这个,但你试过吗

Query query = em.createQuery("FROM PropField propField WHERE propField.name IN elements(?)");
query.setParameter(1, names);