Spring Boot 3升级后JPQL查询报错:ARRAY_REMOVE相关空指针
解决Spring Boot 3.2.2(Hibernate 6.4.1)中JPQL数组更新的NullPointerException问题
针对升级后出现的ARRAY_REMOVE调用NPE问题,可从以下几个方向排查修复:
1. 调整数组字段的JDBC类型映射配置
Hibernate 6对类型映射的处理更严格,原@JdbcTypeCode(SqlTypes.ARRAY)可能无法正确适配List<Long>与数据库数组的绑定。建议替换为更明确的类型配置:
@Entity public class Rules { // 其他字段 @Column(columnDefinition = "bigint[]") // 根据数据库类型调整,比如PostgreSQL用bigint[],MySQL用json或其他数组类型 @JdbcType(ArrayJdbcType.class) private List<Long> messageDepartmentIds; // getter/setter }
如果是MySQL等不原生支持数组的数据库,建议改用@JdbcTypeCode(SqlTypes.JSON)将List存储为JSON类型,再对应调整更新语句的函数(比如用JSON_ARRAY_REMOVE)。
2. 修正JPQL的FUNCTION调用逻辑
Hibernate 6对JPQL函数解析的规则有变化,需确保ARRAY_REMOVE的参数传递符合要求,同时避免处理null数组:
方案A:完善JPQL的空值判断
@Modifying @Query("UPDATE Rules r SET r.messageDepartmentIds = CASE WHEN r.messageDepartmentIds IS NOT NULL THEN FUNCTION('ARRAY_REMOVE', r.messageDepartmentIds, :deptId) ELSE r.messageDepartmentIds END WHERE r.id = :ruleId") void removeDeptFromRules(@Param("ruleId") Long ruleId, @Param("deptId") Long deptId);
方案B:改用原生SQL查询(绕过JPQL解析问题)
@Modifying @Query(value = "UPDATE rules SET message_department_ids = array_remove(message_department_ids, :deptId) WHERE id = :ruleId", nativeQuery = true) void removeDeptFromRulesNative(@Param("ruleId") Long ruleId, @Param("deptId") Long deptId);
3. 排查NPE的直接触发点
检查执行更新时是否存在messageDepartmentIds为null的Rules实体——部分数据库的ARRAY_REMOVE函数在处理null数组时会抛出异常,可在业务逻辑层先判断并初始化空数组,再执行更新操作。
内容的提问来源于stack exchange,提问作者FPS Bard
相关产品推荐
相关产品推荐

