You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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类型映射

  1. 在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,
    
  2. 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方法
    }
    
  3. 修改Hibernate参数注册
    注册输出参数时使用上述实体类:

    query.registerStoredProcedureParameter("Table1", Table1Type.class, ParameterMode.OUT);
    

方案二:拆分输出参数为单个列

如果无法修改存储过程,可将%ROWTYPE对应的表列拆分为独立的输出参数:

  1. 注册单个列作为输出参数
    假设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);
    
  2. 执行后组装对象
    调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 05:13:11