【问题标题】:JPA EntityManager createQuery() with IN not working带有 IN 的 JPA EntityManager createQuery() 不起作用
【发布时间】:2011-03-08 00:23:44
【问题描述】:

这失败了:

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。

【问题讨论】:

    标签: java hibernate orm jpa


    【解决方案1】:

    来自 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 进行了测试。

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

    【讨论】:

      【解决方案2】:

      我在使用带有 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

      【讨论】:

      • 就在您发布之前,我将其更改为“IN (:my_list)”,然后使用 setParameter("my_list", names);您的方法实际上是相同的。谢谢。
      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-02
        • 2012-04-12
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多