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

Spring Boot 3.2.11升级至3.4.1:Hibernate更新语句转Update Select报错

Spring Boot 3.4.1升级后HQL更新语句SQL语法错误原因分析

问题场景

将项目从Spring Boot 3.2.11升级到3.4.1后,执行一段简单的HQL更新语句时,Hibernate生成的SQL出现语法错误,错误提示update [*](select ...)存在语法问题,数据库无法识别该语句格式。

所用HQL代码

"update Account a set "
+ "a.lastDefBalance = null,"
+ "a.lastDefExtractNum = null,"
+ "a.lastPrevAccountNum = null,"
+ "a.lastDefAccountNum = null,"
+ "a.lastDefWithMovsJC = null,"
+ "a.lastDefJC = null,"
+ "a.bic11RefPerJC = null,"
+ "a.lastPrevItgtDatetime = null,"
+ "a.lastDefItgtDatetime = null,"
+ "a.lastDefRcptDatetime = null,"
+ "a.lastDefERRcptDatetime = null,"
+ "a.lastDefIntegratedRcptDatetime = null,"
+ "a.nextJC = null,"
+ "a.thalerStatus = null where a.id = :id" 

报错信息

AccountRepositoryTest.resetAccountDataContinuityByBic11:168 »
InvalidDataAccessResourceUsage could not prepare statement [Erreur de
syntaxe dans l'instruction SQL "update [*](select
a1_0.LAST_DEF_BALANCE c0,null c1,a1_0.LAST_DEF_EXTRACTNUM c2,null
c3,a1_0.LAST_PREV_ACCOUNTNUM c4,null c5,a1_0.LAST_DEF_ACCOUNTNUM
c6,null c7,a1_0.LAST_DEF_MOVS_JC c8,null c9,a1_0.LAST_DEF_JC c10,null
c11,a1_0.BIC11REF_PERJC c12,null c13,a1_0.LAST_PREV_ITGT c14,null
c15,a1_0.LAST_DEF_ITGT c16,null c17,a1_0.LAST_DEF_RCPT c18,null
c19,a1_0.LAST_DEF_ER_RCPT c20,null c21,a1_0.LAST_DEF_ITGT_RCPT
c22,null c23,a1_0.NEXT_JC c24,null c25,a1_0.THALER_STATUS c26,null c27
from ACCOUNT a1_0 join BANK b1_0 on
b1_0.ID_THALER_BANK=a1_0.ID_THALER_BANK where b1_0.BIC=? and
b1_0.BRANCH_CODE=?) t set
t.c0=t.c1,t.c2=t.c3,t.c4=t.c5,t.c6=t.c7,t.c8=t.c9,t.c10=t.c11,t.c12=t.c13,t.c14=t.c15,t.c16=t.c17,t.c18=t.c19,t.c20=t.c21,t.c22=t.c23,t.c24=t.c25,t.c26=t.c27";
attendu "identifier"

Syntax error in SQL statement "update [*](select a1_0.LAST_DEF_BALANCE
c0,null c1,a1_0.LAST_DEF_EXTRACTNUM c2,null
c3,a1_0.LAST_PREV_ACCOUNTNUM c4,null c5,a1_0.LAST_DEF_ACCOUNTNUM
c6,null c7,a1_0.LAST_DEF_MOVS_JC c8,null c9,a1_0.LAST_DEF_JC c10,null
c11,a1_0.BIC11REF_PERJC c12,null c13,a1_0.LAST_PREV_ITGT c14,null
c15,a1_0.LAST_DEF_ITGT c16,null c17,a1_0.LAST_DEF_RCPT c18,null
c19,a1_0.LAST_DEF_ER_RCPT c20,null c21,a1_0.LAST_DEF_ITGT_RCPT
c22,null c23,a1_0.NEXT_JC c24,null c25,a1_0.THALER_STATUS c26,null c27
from ACCOUNT a1_0 join BANK b1_0 on
b1_0.ID_THALER_BANK=a1_0.ID_THALER_BANK where b1_0.BIC=? and
b1_0.BRANCH_CODE=?) t set
t.c0=t.c1,t.c2=t.c3,t.c4=t.c5,t.c6=t.c7,t.c8=t.c9,t.c10=t.c11,t.c12=t.c13,t.c14=t.c15,t.c16=t.c17,t.c18=t.c19,t.c20=t.c21,t.c22=t.c23,t.c24=t.c25,t.c26=t.c27";
expected "identifier"; SQL statement:

原因分析

  1. Hibernate版本变更导致SQL生成策略改变
    Spring Boot 3.4.1对应的Hibernate版本为6.5.x,相比3.2.11对应的6.4.x版本,Hibernate默认启用了新的更新转换策略(update_transform_strategy)。该策略会将简单的实体UPDATE语句转换为包含子查询的形式,而这种UPDATE (SELECT ...)语法并非所有数据库都支持(例如MySQL 8.0以下、部分版本的H2数据库等)。

  2. 错误引入关联表JOIN
    从生成的SQL可以看到,Hibernate在子查询中意外加入了ACCOUNT与BANK表的JOIN,这与原HQL中仅通过a.id = :id过滤的逻辑不符。这可能是因为Account实体与Bank实体存在关联映射,Hibernate在新版本中错误地将关联关系纳入了UPDATE语句的生成逻辑,导致生成的SQL包含不必要的JOIN操作,进一步触发语法错误。

  3. 字段批量设为null的特殊处理
    原HQL中批量将多个字段设为null,Hibernate新版本的SQL生成逻辑可能对这种批量更新场景的处理方式发生了变化,错误地采用子查询包装的形式,而非直接生成UPDATE ACCOUNT SET ... WHERE id = ?的简单语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:50:56