使用 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_string
和 string_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 中延迟加载的 @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