You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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不再自动进行隐式类型转换,因此触发类型不匹配报错。

修复方法

  1. 显式类型转换:在JPQL中用cast()函数把整数类型转为字符串后再调用trim():
@NamedQuery(name = "findTestTable", query = "SELECT e FROM TestTable e " +
        "WHERE trim(cast(e.Column2 as string)) = trim(cast(:id as string)) ")
  1. 移除不必要的trim:如果Column2是整数类型,本身不存在首尾空格,可直接去掉trim()函数,简化查询:
@NamedQuery(name = "findTestTable", query = "SELECT e FROM TestTable e " +
        "WHERE e.Column2 = :id ")
  1. 参数类型对齐:调用该NamedQuery时,确保传入的:id参数类型与Column2的int类型一致,避免额外的类型转换开销。

额外建议

  • 升级后需全面检查所有JPQL查询的函数使用,Hibernate 6.x对类型兼容性要求更高,trim()、concat()等函数都需要参数类型匹配。
  • 确认Hibernate方言配置正确,SQLServerDialect在Hibernate 6.x中已更新,可考虑使用org.hibernate.dialect.SQLServer2012Dialect或更高版本,适配SQL Server特性。

内容的提问来源于stack exchange,提问作者Nani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:13:29