JPA调用存储过程触发getResultList相关IllegalStateException异常如何解决
异常原因
这个Current CallableStatement ou was not a ResultSet, but getResultList was called异常本质是JPA(Hibernate实现)调用存储过程后,没有检测到可用的结果集,但代码主动调用了getResultList()方法读取结果,常见触发原因有3种:
- 调用的
SPCL_LIST_BEN_UNI_ID存储过程本身没有直接通过SELECT返回结果集,而是通过OUT参数返回数据 - 存储过程返回了结果集,但JPA调用时没有提前声明结果集映射,Hibernate无法识别到结果集
- 调用
execute()后没有判断返回值,存储过程本次执行没有产生结果集时依然调用了getResultList()
对应修复方案
场景1:存储过程直接通过SELECT返回结果集
修改代码,提前声明结果集类型,同时增加结果集存在性判断:
EntityManager em = entityManagerFactory.createEntityManager(); // 第二个参数为结果集映射,根据实际返回的数据类型填写,比如返回字符串填String.class,返回自定义实体填对应的实体类class StoredProcedureQuery proc = em.createStoredProcedureQuery("SPCL_LIST_BEN_UNI_ID", String.class); // 注册IN参数和原有逻辑一致 proc.registerStoredProcedureParameter("p_adt_usr_id", String.class, ParameterMode.IN); proc.registerStoredProcedureParameter("p_lng", String.class, ParameterMode.IN); proc.registerStoredProcedureParameter("p_act_id", String.class, ParameterMode.IN); proc.setParameter("p_adt_usr_id", "HALLAGE1"); proc.setParameter("p_lng", "ENG"); proc.setParameter("p_act_id", "1AN76VZ"); // execute返回true代表当前有可用结果集,再读取结果 if (proc.execute()) { List resultList = proc.getResultList(); // 后续业务逻辑处理resultList } // 也可以省略execute()直接调用getResultList,Hibernate内部会自动执行并校验结果集存在性 // List resultList = proc.getResultList();
场景2:存储过程通过OUT参数返回结果集(比如Oracle的REF_CURSOR)
需要额外注册OUT参数,执行后读取参数值获取结果:
EntityManager em = entityManagerFactory.createEntityManager(); StoredProcedureQuery proc = em.createStoredProcedureQuery("SPCL_LIST_BEN_UNI_ID"); // 注册IN参数 proc.registerStoredProcedureParameter("p_adt_usr_id", String.class, ParameterMode.IN); proc.registerStoredProcedureParameter("p_lng", String.class, ParameterMode.IN); proc.registerStoredProcedureParameter("p_act_id", String.class, ParameterMode.IN); // 注册OUT参数,参数名、类型和存储过程定义保持一致,Oracle的游标类型填void.class或者OracleTypes.CURSOR proc.registerStoredProcedureParameter("p_result", void.class, ParameterMode.REF_CURSOR); proc.setParameter("p_adt_usr_id", "HALLAGE1"); proc.setParameter("p_lng", "ENG"); proc.setParameter("p_act_id", "1AN76VZ"); proc.execute(); // 读取OUT参数的值获取结果集 List resultList = (List) proc.getOutputParameterValue("p_result");
额外排查项
如果以上修改还是报错,先在数据库客户端直接执行存储过程,确认传入参数一致的情况下确实能返回预期结果,排除存储过程本身逻辑问题导致无结果集返回的情况。
内容的提问来源于stack exchange,提问作者sathya p
相关产品推荐
相关产品推荐

