这是失败的:
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。
答案 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);