使用 JPA 2.1 / Hibernate 4 将值列表传递给存储过程

Posted

技术标签:

【中文标题】使用 JPA 2.1 / Hibernate 4 将值列表传递给存储过程【英文标题】:Passing a list of values to a stored procedure using JPA 2.1 / Hibernate 4 【发布时间】:2015-10-20 18:02:57 【问题描述】:

我有一个接收字符串列表的存储过程(并遵循存储过程的限制,according to Hibernate docs):

PROCEDURE count_active_esc(p_count OUT NUMBER, p_codes IN string_list);

其中string_list 是自定义类型:

CREATE OR REPLACE TYPE string_list IS TABLE OF VARCHAR(100)

并想从 JPA 实体管理器 (a new feature in JPA 2.1) 调用它。

我尝试使用数组:

StoredProcedreQuery query = entityManager.createNamedStoredProcedureQuery("count_active_esc");
query.registerStoredProcedureParameter("p_count", Integer.class, ParameterMode.OUT);
query.registerStoredProcedureParameter("p_codes", String[].class, ParameterMode.IN);
query.setParameter("p_codes", new String[]  "AEST" );

query.getOutputParameterValue("p_count"); // <<<<< throws an exception

得到一个异常:

    PLS-00306: wrong number or types of arguments in call to 'COUNT_ACTIVE_ESC'
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored

如果我传入一个列表:

StoredProcedreQuery query = entityManager.createNamedStoredProcedureQuery("count_active_esc");
query.registerStoredProcedureParameter("p_count", Integer.class, ParameterMode.OUT);
query.registerStoredProcedureParameter("p_codes", List.class, ParameterMode.IN); // <<<<< throws an exception
query.setParameter("p_codes", new ArrayList<String>  "AEST" );

query.getOutputParameterValue("p_count");

它抛出java.lang.IllegalArgumentException: Type cannot be null

另外添加 query.setHint("org.hibernate.callable", "true") 也没有帮助。

在 JPA 或 Hibernate 中执行此操作的正确方法是什么?不借助 JDBC 是否有可能?

环境:JPA 2.1、Hibernate 4.3.5、Oracle

【问题讨论】:

我遇到了类似的问题。你找到解决办法了吗? AFAIK Hibernate 不在 SP 调用中自定义类型。所以我不得不使用普通的 JDBC。 EclipseLink's PLSQLStoredProcedureCall 似乎也能解决问题。 是的——事实上,我得出了类似的结论——Hibernate 和 JPA 标准似乎都没有明确支持复杂的 SQL 类型:“JPA 不支持对象关系数据类型,但是一些 JPA 提供商可能会提供一些支持” (see here)。 (请注意,EclipseLink/TopLink 确实提供了基本支持)。不过,我对该问题的解决方案有所不同 - 我使用 PostgreSQL 的内置函数(分别为 array_to_stringstring_to_array)将我试图通过的数组作为简单的 VARCHAR 值偷偷摸摸。 @PriiduNeemre,您愿意分享您的解决方案吗? 嗨.. 它仍然是一个限制吗.. 我试图将类似的 varchar 类型数组作为 OUT 变量.. 我得到与你指定的相同的错误。最终的解决方案是什么? 【参考方案1】:

将 Integer.class 更改为 Types.INTEGER

【讨论】:

在以下情况下将不起作用:StoredProcedureQuery javax.persistence.StoredProcedureQuery.registerStoredProcedureParameter(String arg0, Class arg1, ParameterMode arg2)

以上是关于使用 JPA 2.1 / Hibernate 4 将值列表传递给存储过程的主要内容,如果未能解决你的问题,请参考以下文章

Glassfish 4 JDBC 资源连接失败,Hibernate 4.3.5 和 JPA 2.1 连接分配由于数据库“null”而被拒绝

哪个版本的hibernate支持jpa 2.1?

在 Hibernate / JPA 2.1 中延迟加载的 @OneToOne 映射不起作用?

Spring Boot 2.1 缺少多个 org.hibernate.jpa.event 类

使用 Hibernate JPA 2.1 将应用程序部署到 IBM WebSphere 会产生 NullPointerException

当加载 spring-boot 和 spring-data-jpa 时,Hibernate 无法加载 JPA 2.1 Converter