使用Hibernate调用含表行类型输出参数的存储过程报错求助
Oracle存储过程ROWTYPE输出参数的Hibernate调用问题
问题场景
Oracle存储过程代码
CREATE OR REPLACE PACKAGE BODY Pkg_name IS PROCEDURE proceure_Name ( Id IN Long, startDate IN DATE, EndDate IN DATE, Table1 OUT Table1_Name%ROWTYPE, Table2 OUT Table2_Name%ROWTYPE, errormsg OUT VARCHAR2) IS Record another_Table%ROWTYPE;
Hibernate调用代码
Long id = 111111111111111L; Date startDate = setDateTime("08/31/2023 00:00:00"); Date endDate = setDateTime("09/01/2018 00:00:00"); // 声明存储过程 StoredProcedureQuery query = this.em.createStoredProcedureQuery("package_name.procedure_name"); // 输入参数 query.registerStoredProcedureParameter("Id", Long.class, ParameterMode.IN); query.setParameter("in_regEntId", id); query.registerStoredProcedureParameter("startDate", Date.class, ParameterMode.IN); query.setParameter("in_chPeriodStartDate", startDate); query.registerStoredProcedureParameter("EndDate", Date.class, ParameterMode.IN); query.setParameter("in_chPeriodEndDate", endDate); // 注册输出参数 query.registerStoredProcedureParameter("Table1", Table1_name.class, ParameterMode.OUT); query.registerStoredProcedureParameter("Table2", Table2_name.class, ParameterMode.OUT); query.registerStoredProcedureParameter("errormsg", String.class, ParameterMode.OUT); // 执行存储过程 query.execute();
遇到的问题
注册输出参数时提示Table1_name类型无效,无法直接用Java实体类映射Oracle存储过程中的%ROWTYPE输出参数。
解决方案
Hibernate对Oracle专属的%ROWTYPE类型支持有限,因为它不属于标准SQL类型,可通过以下两种方式解决:
方案一:改用Oracle自定义OBJECT类型映射
在Oracle中创建对应行类型的OBJECT
针对Table1_Name表的结构,创建一个匹配的OBJECT类型:CREATE OR REPLACE TYPE TABLE1_TYPE AS OBJECT ( -- 按Table1_Name的列定义逐一添加,示例如下 id NUMBER, name VARCHAR2(100), create_date DATE );然后修改存储过程的输出参数类型为该OBJECT(替换原有的
Table1_Name%ROWTYPE):Table1 OUT TABLE1_TYPE,Java端创建映射实体类
用@Struct注解绑定Oracle的OBJECT类型:@Struct(name = "TABLE1_TYPE", fields = {"id", "name", "create_date"}) public class Table1Type { private Long id; private String name; private Date createDate; // 全参构造器、getter/setter方法 }修改Hibernate参数注册
注册输出参数时使用上述实体类:query.registerStoredProcedureParameter("Table1", Table1Type.class, ParameterMode.OUT);
方案二:拆分输出参数为单个列
如果无法修改存储过程,可将%ROWTYPE对应的表列拆分为独立的输出参数:
注册单个列作为输出参数
假设Table1_Name包含id、name、create_date三列,分别注册:query.registerStoredProcedureParameter("Table1_id", Long.class, ParameterMode.OUT); query.registerStoredProcedureParameter("Table1_name", String.class, ParameterMode.OUT); query.registerStoredProcedureParameter("Table1_create_date", Date.class, ParameterMode.OUT);执行后组装对象
调用query.execute()后,逐个获取参数值并组装成Java实体:Long table1Id = (Long) query.getOutputParameterValue("Table1_id"); String table1Name = (String) query.getOutputParameterValue("Table1_name"); Date table1CreateDate = (Date) query.getOutputParameterValue("Table1_create_date"); Table1_name table1 = new Table1_name(); table1.setId(table1Id); table1.setName(table1Name); table1.setCreateDate(table1CreateDate);
内容的提问来源于stack exchange,提问作者Justanewbie
相关产品推荐
相关产品推荐

