SpringBoot 2.7升级3.1后HQL trim函数类型不匹配报错
SpringBoot 2.7升级至3.1后NamedQuery启动报错
问题背景
将SpringBoot应用从2.7版本升级至3.1版本后,原有查询、POM配置及application.properties在2.7版本中运行正常,但3.x版本启动时出现异常。
相关代码与配置
查询代码
package com.dba.tableQuery; import jakarta.persistence.*; import java.io.Serializable; import java.sql.Timestamp; @Entity @Table(name="TestTable") @NamedQuery(name = "findTestTable", query = "SELECT e FROM TestTable e " + "WHERE trim(e.Column2) = trim(:id) ") public class TableQuery implements Serializable { @EmbeddedId private TestTablePK id; @Column(name="Column2", insertable=false, updatable=false) private int column2; @Column(name="Column3", insertable=false, updatable=false) private String column3; @Column(name="Column4", insertable=false, updatable=false) private String column4; //getter and setter are declared }
POM依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>11.2.3.jre17</version> </dependency>
application.properties配置
#Datasource configuration spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect spring.jpa.hibernate.ddl-auto=none spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true spring.jpa.properties.hibernate.proc.param_null_passing=true spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl spring.jpa.show-sql=false spring.jpa.properties.hibernate.format_sql=false #SQL logging configuration spring.datasource.url=jdbc:sqlserver://test;databaseName=testTable;encrypt=true;trustServerCertificate=true spring.datasource.username=testUser spring.datasource.password=testPassword
报错信息
启动应用时抛出异常:
Error in named query: findTestTable org.hibernate.QueryException: Parameter 3 of function trim() has type STRING, but argument is of type java.lang.Integer ...(省略栈信息) org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.HibernateException: Errors in named queries: findTestTable
已尝试方案
曾参考过SpringBoot 3升级中函数兼容问题的相关方案,但未解决当前问题。
解决方案
原因分析
SpringBoot 3.x对应的Hibernate 6.x版本对JPQL函数的类型检查变得更严格。原代码中e.Column2是int类型,而trim()函数在JPQL中仅支持字符串类型参数,Hibernate 6.x不再自动进行隐式类型转换,因此触发类型不匹配报错。
修复方法
- 显式类型转换:在JPQL中用
cast()函数把整数类型转为字符串后再调用trim():
@NamedQuery(name = "findTestTable", query = "SELECT e FROM TestTable e " + "WHERE trim(cast(e.Column2 as string)) = trim(cast(:id as string)) ")
- 移除不必要的trim:如果
Column2是整数类型,本身不存在首尾空格,可直接去掉trim()函数,简化查询:
@NamedQuery(name = "findTestTable", query = "SELECT e FROM TestTable e " + "WHERE e.Column2 = :id ")
- 参数类型对齐:调用该NamedQuery时,确保传入的
:id参数类型与Column2的int类型一致,避免额外的类型转换开销。
额外建议
- 升级后需全面检查所有JPQL查询的函数使用,Hibernate 6.x对类型兼容性要求更高,
trim()、concat()等函数都需要参数类型匹配。 - 确认Hibernate方言配置正确,SQLServerDialect在Hibernate 6.x中已更新,可考虑使用
org.hibernate.dialect.SQLServer2012Dialect或更高版本,适配SQL Server特性。
内容的提问来源于stack exchange,提问作者Nani
相关产品推荐
相关产品推荐

