为什么Long数组作为JPA原生查询IN条件参数会报SQL语法错误?
异常产生原因
- SQL语法层面:IN子句后需要用括号包裹参数列表,你当前写的
where id in ?1缺少括号,不符合SQL语法规范。 - 参数处理层面:JPA的
setParameter默认无法自动展开数组类型参数为IN子句所需的多值结构,直接传入Long数组时,Hibernate会将整个数组做Java序列化处理后作为单个字符串代入SQL,你异常信息里ACED0005开头的乱码就是Java序列化后的固定标识,最终拼接出的SQL完全不符合语法要求,因此抛出SQLSyntaxErrorException。
解决方案
修正SQL写法+转换数组为List传入
修改后代码如下:
import java.util.Arrays; import java.util.List; @Service public class Executor { @Autowired private EntityManager entityManager; @Transactional public void deleteRows(Long[] ids, String table) { // 对表名做白名校验,避免SQL注入风险,可根据实际业务调整允许的表名列表 if (!List.of("test_table", "allow_table1", "allow_table2").contains(table)) { throw new IllegalArgumentException("非法表名参数"); } entityManager.createNativeQuery("update " + table + " set flag = 0 where id in (?1) ") .setParameter(1, Arrays.asList(ids)) .executeUpdate(); } }
- 修正IN子句的写法,添加括号包裹参数位
- 将Long数组转为List类型传入参数,Hibernate会自动将List中的元素展开为IN子句的多值参数,生成合法的SQL语句
- 额外添加表名白名校验,避免直接拼接表名带来的SQL注入安全隐患
内容的提问来源于stack exchange,提问作者java dev
相关产品推荐
相关产品推荐

