【问题标题】:Saying position beyond number of declared ordinal parameters说位置超出了声明的序数参数的数量
【发布时间】:2012-10-16 06:59:51
【问题描述】:

我想使用 hibernate 执行原生/原始 mysql 查询,我有这个:

 sessionFactory.getCurrentSession().createSQLQuery(
       "update table1 set someCounter = someCounter + 1 where id = ?")
     .setParameter(1, someId)
     .executeUpdate();

我收到了错误:

threw exception [Request processing failed; nested exception is
      org.hibernate.QueryParameterException: Position beyond number of declared ordinal
      parameters. Remember that ordinal parameters are 1-based! Position: 2] 
      with root cause
      org.hibernate.QueryParameterException: Position beyond number of declared ordinal
      parameters. Remember that ordinal parameters are 1-based! Position: 2

这里有什么问题?

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    使用索引作为0,因为参数索引从0开始。

    sessionFactory.getCurrentSession()
      .createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
      .setParameter(0, someId)
      .executeUpdate();
    

    由于您使用的是 Hibernate,因此您也可以使用命名参数,即

    sessionFactory.getCurrentSession()
      .createSQLQuery("update table1 set someCounter = someCounter + 1 where id = :id")
      .setParameter("id", someId)
      .executeUpdate();
    

    【讨论】:

    【解决方案2】:

    参数使用从零开始的索引。试试:

     sessionFactory.getCurrentSession().createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
                    .setParameter(0, someId)
                    .executeUpdate();
    

    当前的 Hibernate JavaDocs 还指定 setPosition 依赖于位置参数的基于零的索引。 http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/Query.html#setParameter%28int,%20java.lang.Object%29

    setParameter
    
    Query setParameter(int position,
                       Object val)
                       throws HibernateException
    
        Bind a value to a JDBC-style query parameter. The Hibernate type of the parameter is first detected via the usage/position in the query and if not sufficient secondly guessed from the class of the given object.
    
        Parameters:
            position - the position of the parameter in the query string, numbered from 0.
            val - the non-null parameter value 
        Throws:
            HibernateException - if no type could be determined
    

    查看本文档的参数部分:https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_Web_Server/1.0/html/Hibernate_Core_Reference_Guide/querysql.html#id3043464

    关于 setParameter() 方法是从零开始还是从一开始,已经有一些讨论。这种混淆是由于张贴者收到的异常指出参数是从 1 开始的,而 JavaDoc 声明它们是从零开始的。我分析了 Hibernate 源代码并相信它们实际上是从零开始的。假设我检查了正确的类,底层代码使用一个列表来存储参数绑定值,这意味着 setParameter 方法实际上是从零开始的。自己查看源代码:https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java

    【讨论】:

      【解决方案3】:

      Positional 参数从0 而不是1 开始

      原生 SQL 查询支持位置参数和命名参数:

      通过在 setParameter(1, someId) 中传递 0 而不是 1 来更新您的查询

      sessionFactory.getCurrentSession().createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
                      .setParameter(0, someId)
                      .executeUpdate();
      

      资源parameters

      【讨论】:

        【解决方案4】:

        对于那些无法根据上述解决方案解决的人来说,似乎有时休眠(取决于版本,我使用的是 3)实际上会给您错误的错误,例如问题可能存在如果在 hibernate q 语言中出现语法错误:

        find("from Student s where s.id = :id")
        

        改成这样:

        find("from Student s where s.id = ?")
        

        实际上解决了这个问题。我想我的主要观点是,您还应该查看问题的语法,因为 hibernate 似乎可以错误地标记此异常。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-18
          • 2012-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多