项目hibernate3.2.16升级hibernate5.5.7时,HQL语句使用"?"参数占位符运行报错,国内查到的都是这样改(基本都是改HQL语句参数,使用起来也没问题):
第一种
String hql = "from UserForm where sex=?"; //定义查询HQL语句
Query query = session.createQuery(hql); //执行查询语句,获取Query对象
query.setString(0,"女"); //设置HQL语句参数
第二种
String hql = "from UserForm where sex=:sex"; //定义查询HQL语句
Query query = session.createQuery(hql); //执行查询语句获取Query对象
query.setString("sex","女"); //设置HQL语句参数
但是公司项目比较大,懒得一个个改,于是在外网找解决方法,找到了官方文档:
Changes to positional query parameter handling
This really breaks down into 2 related changes:
-
Support for JDBC-style parameter declarations in HQL/JPQL queries has been removed. This feature has been deprecated since 4.1 and removing it made implementing the second change, so we decided to remove that support. JDBC-style parameter declaration is still supported in native-queries.
-
Since JPA positional parameters really behave more like named parameters (they can be repeated, declared in any order, etc.) Hibernate used to treat them as named parameters - it relied on Hibernate’s JPA wrapper to interpret the JPA setParameter calls and properly handle delegating to the named variant. This is actually a regression in 5.2 as it causes
javax.persistence.Parameter#getPosition
to reportnull
.
For JDBC-style parameter declarations in native queries, we have also moved to using one-based instead of zero-based parameter binding to be consistent with JPA. That can temporarily be reverted by setting the hibernate.query.sql.jdbc_style_params_base
setting to true
which reverts to expecting zero-based binding.
翻译为:
位置查询参数处理的更改
这可以分为两个相关的变化:
-
HQL/JPQL查询中对jdbc样式参数声明的支持已被删除。这个特性从4.1开始就被弃用了,删除它是为了实现第二次更改,所以我们决定删除这个支持。在本机查询中仍然支持jdbc样式的参数声明。
-
由于JPA位置参数的行为实际上更像命名参数(它们可以重复、以任何顺序声明,等等),Hibernate通常将它们视为命名参数——它依赖于Hibernate的JPA包装器来解释JPA setParameter调用,并正确地处理对命名变量的委托。这实际上是5.2中的回归,因为它导致javax.persistence。参数#getPosition报告空。
对于本机查询中的jdbc样式的参数声明,我们也转而使用基于1的参数绑定,而不是基于0的参数绑定,以与JPA保持一致。可以通过设置hibernate.query.sql来临时恢复。Jdbc_style_params_base设置为true,将返回到期望的基于零的绑定。
重点:
That can temporarily be reverted by setting the hibernate.query.sql.jdbc_style_params_base
setting to true
which reverts to expecting zero-based binding.
可以通过设置hibernate.query.sql来临时恢复。Jdbc_style_params_base设置为true,将返回到期望的基于零的绑定。
于是在xml中配置
<prop key="hibernate.query.sql.jdbc_style_params_base">true</prop>
重启测试,可以了。国内外网上的资料都很少,可能是hibernate落寞的原因。