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

Spring Boot 3中JPA含分号查询分页失效问题求助

Spring Boot 3 JPA原生查询分页时分号解析异常问题

问题背景

在Spring Boot 3中编写带分号的JPA原生查询,示例代码如下:

@Query(value=".... LIKE CONCAT(?, '%;') ...")

最终生成的SQL会被错误改写为:

LIKE CONCAT(?, '% limit ?;')

尝试用反斜杠转义分号无效,但相同代码在Spring Boot 2.7中可正常运行。

补充测试场景:

  • 返回List的普通查询能正常执行:
@Query(value = "SELECT u.* FROM user u WHERE u.userId LIKE CONCAT(?1, '%;') OR u.userId IN ?2", nativeQuery = true)
List<UserEntity> search(String search, List<String> userIds);
  • 改为返回Page并添加Pageable分页参数后,查询直接失败。

问题原因

Spring Boot 3配套升级了Hibernate至6.x版本,Hibernate 6.x对原生查询的SQL解析逻辑做了调整:当处理带分页的原生查询时,框架会自动拼接limit/offset语句,但解析器会误将查询字符串中的';'识别为SQL语句的结束标记,导致把%;拆分为%和;,进而错误地将分页的limit插入到CONCAT语句中间,破坏了原有的拼接逻辑。

而Spring Boot 2.7使用的Hibernate 5.x版本不存在该解析问题,因此旧版本中代码可正常运行。

解决办法

以下是几种可行的解决方案:

1. 将分号作为参数传入

避免在原生SQL中硬写';',把它作为单独参数传递:

@Query(value = "SELECT u.* FROM user u WHERE u.userId LIKE CONCAT(?1, ?2) OR u.userId IN ?3", nativeQuery = true)
Page<UserEntity> search(String search, String suffix, List<String> userIds, Pageable pageable);

调用时传入suffix = ";"即可,这样解析器不会把分号当成语句结束符。

2. 手动指定count查询

分页查询时JPA会自动生成count统计查询,手动指定count查询可强制Hibernate分别解析主查询和count查询,避免解析错误:

@Query(
    value = "SELECT u.* FROM user u WHERE u.userId LIKE CONCAT(?1, '%;') OR u.userId IN ?2",
    countQuery = "SELECT COUNT(*) FROM user u WHERE u.userId LIKE CONCAT(?1, '%;') OR u.userId IN ?2",
    nativeQuery = true
)
Page<UserEntity> search(String search, List<String> userIds, Pageable pageable);

3. 用ASCII码替代分号(数据库兼容方案)

针对支持ASCII函数的数据库(如MySQL、PostgreSQL),用CHAR(59)代替直接写';'(59是分号的ASCII编码):

@Query(value = "SELECT u.* FROM user u WHERE u.userId LIKE CONCAT(?1, '%', CHAR(59)) OR u.userId IN ?2", nativeQuery = true)
Page<UserEntity> search(String search, List<String> userIds, Pageable pageable);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:30:02