Spring Boot通过JDBC调用Oracle存储过程返回空结果问题排查
问题根本原因
- 命名存储过程查询不匹配:你在
PathwaysJourney实体类上通过@NamedStoredProcedureQuery定义的查询名称为test_stored_proc_sp,但控制器中调用em.createNamedStoredProcedureQuery()时传入的名称是Test_stored_proc,二者拼写、大小写不一致,JPA无法加载你定义在实体上的映射配置。 - 存储过程参数、结果映射缺失:你写的
@NamedStoredProcedureQuery没有声明任何参数,也没有指定结果集映射类。Oracle存储过程返回结构化结果集依赖SYS_REFCURSOR类型的OUT出参,不声明该参数的情况下,JPA执行完存储过程不会主动读取结果集出参,直接返回空列表。 - 对
set serveroutput on的认知错误:这个命令是SQL Developer、sqlplus这类Oracle交互式客户端的内置专属命令,不属于标准SQL语法,JDBC驱动无法识别执行。它的作用仅为开启客户端对DBMS_OUTPUT.PUT_LINE打印文本的抓取展示,和存储过程返回结构化结果集完全无关,你在SQL Developer中能查到数据是存储过程通过REF_CURSOR出参返回的结果,和serveroutput开关没有关系,不需要在Spring Boot中执行这条命令。
具体修复方案
- 修正实体类上的
@NamedStoredProcedureQuery配置,补全参数声明和结果映射,保证命名和后续调用一致:
@NamedStoredProcedureQuery( name = "test_stored_proc_sp", procedureName = "Test_stored_proc", // 按存储过程实际参数顺序声明,以下示例为无入参、仅一个REF_CURSOR出参返回结果的场景 parameters = { @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, type = void.class) }, // 指定结果集映射到的实体类 resultClasses = PathwaysJourney.class )
如果你的存储过程存在入参,需要按照参数定义顺序在
parameters数组中补充对应配置,mode设为ParameterMode.IN,匹配正确的参数类型即可。如果返回字段名和实体类字段名不一致,需要在实体类字段上加@Column(name = "数据库列名")做映射。
- 修正控制器中的调用逻辑,传入正确的命名查询名称,删除无用的serveroutput相关代码:
@PostMapping("/pathwaysjourney1") @ResponseBody public List<PathwaysJourney> getAllPathways1() { StoredProcedureQuery proc = this.em.createNamedStoredProcedureQuery("test_stored_proc_sp"); // 若有入参,在此处通过proc.setParameter(位置/参数名, 参数值)绑定 proc.execute(); return proc.getResultList(); }
额外排查点
- 确认项目引入的ojdbc驱动版本和Oracle数据库版本匹配,避免REF_CURSOR解析异常。
- 可以通过
show-sql打印的执行日志,确认存储过程调用语句、参数绑定是否符合预期,必要时可以直接通过JDBC原生Connection调用存储过程做对比测试,排除JPA映射问题。
内容的提问来源于stack exchange,提问作者Befekadu Asmare
相关产品推荐
相关产品推荐

