SpringBoot 2.7升级至3.1后JPA存储过程调用预准备失败原因?
我们的Informix数据库中有如下存储过程:
CREATE PROCEDURE cp_cno_LinkToTrans(ai_notice_id INTEGER, avc_txn_type VARCHAR(3), ai_txn_id INTEGER);
该存储过程无输出参数、返回行或返回值。之前在SpringBoot 2.7(对应Hibernate 5.6)环境下,使用标注了@Procedure("cp_cno_LinkToTrans")的Spring Data JPA Repository方法(含三个输入参数、无返回值)可正常调用。
升级到SpringBoot 3.1后,出现预准备语句语法错误:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement [A syntax error has occurred.] [{call cp_cno_LinkToTrans(:id,:type,:transId)}]; SQL [{call cp_cno_LinkToTrans(:id,:type,:transId)}]
想知道这是Spring Data存储过程定义方式变了,还是存在相关bug?
1. 核心原因:Hibernate 6的语法适配变更
SpringBoot 3.1对应Hibernate 6.x版本,和Hibernate 5.6相比,存储过程调用的语法生成逻辑有调整。Informix调用无返回值的存储过程时,标准语法是EXECUTE PROCEDURE,但Hibernate 6默认生成了通用的CALL语法,导致Informix解析报错。
2. 可行的修复方案
方案一:用@Query直接写Informix兼容语句
放弃@Procedure,改用原生查询注解直接指定执行语句,绕过Hibernate的存储过程语法生成逻辑:
@Modifying @Query(value = "EXECUTE PROCEDURE cp_cno_LinkToTrans(?1, ?2, ?3)", nativeQuery = true) void cp_cno_LinkToTrans(Integer ai_notice_id, String avc_txn_type, Integer ai_txn_id);
方案二:显式配置存储过程定义
如果坚持用@Procedure,可以在实体类上通过@NamedStoredProcedureQuery定义完整的存储过程参数和调用模式,让Hibernate生成正确的语法:
// 在任意实体类上添加如下注解 @NamedStoredProcedureQuery( name = "cp_cno_LinkToTrans", procedureName = "cp_cno_LinkToTrans", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "ai_notice_id", type = Integer.class), @StoredProcedureParameter(mode = ParameterMode.IN, name = "avc_txn_type", type = String.class), @StoredProcedureParameter(mode = ParameterMode.IN, name = "ai_txn_id", type = Integer.class) } ) // Repository方法调整为带参数绑定的形式 @Procedure(name = "cp_cno_LinkToTrans") void cp_cno_LinkToTrans(@Param("ai_notice_id") Integer ai_notice_id, @Param("avc_txn_type") String avc_txn_type, @Param("ai_txn_id") Integer ai_txn_id);
方案三:检查JDBC驱动兼容性
确保使用的Informix JDBC驱动版本适配SpringBoot 3.x和Hibernate 6.x,旧版本驱动可能无法正确处理新的调用语法。可以尝试升级com.informix.jdbc:ifxjdbc到最新兼容版本。
3. 是否存在bug?
目前来看,这更偏向Hibernate 6对Informix存储过程语法的适配遗漏,而非Spring Data的直接bug。可以查看Hibernate的官方issue列表,确认是否有类似兼容性问题的报告,也可以提交新issue反馈该场景。
内容的提问来源于stack exchange,提问作者Kai

