Can#39;t call PostgreSQL#39;s 11 Stored Procedure with Hibernate(不能用Hibernate调用PostgreSQL的11个存储过程)
问题描述
PostgreSQL 11 现在支持存储过程,我正在尝试使用 Hibernate 5.3.7.Final 和 Postgresql 42.2.5 JDBC 驱动程序 调用一个.在 PostgreSQL 11 之前,我们有可以使用 JPA 的 @NamedStoredProcedure 调用的函数.但是,函数是用 SELECT my_func(); 执行的,新的存储过程必须用 CALL my_procedure();
PostgreSQL 11 now supports stored procedures and I am trying to call one with Hibernate 5.3.7.Final and Postgresql 42.2.5 JDBC driver. Previous to PostgreSQL 11 we had functions that could be called with JPA's @NamedStoredProcedure. However, the functions were executed with SELECT my_func(); and the new stored procedures have to be executed with CALL my_procedure();
我正在尝试执行以下简单的存储过程:
I am trying to execute the following simple stored procedure:
CREATE OR REPLACE PROCEDURE p_raise_wage_employee_older_than(operating_years
int, raise int)
AS $$
BEGIN
UPDATE employees
SET wage = wage + raise
WHERE EXTRACT(year FROM age(entrance_date)) >= operating_years;
END $$
LANGUAGE plpgsql;
JPA 注释如下所示:
The JPA annotation looks like the following:
@NamedStoredProcedureQuery(name = "raiseWage",
procedureName = "p_raise_wage_employee_older_than",
parameters = {
@StoredProcedureParameter(name = "operating_years", type = Integer.class,
mode = ParameterMode.IN),
@StoredProcedureParameter(name = "raise", type = Integer.class,
mode = ParameterMode.IN)
})
我正在调用存储过程:
StoredProcedureQuery storedProcedureQuery = this.em.createNamedStoredProcedureQuery("raiseWage");
storedProcedureQuery.setParameter("operating_years", 20);
storedProcedureQuery.setParameter("raise", 1000);
storedProcedureQuery.execute();
我的日志如下所示:
Hibernate: {call p_raise_wage_employee_older_than(?,?)}
2019-02-17 11:07:41.290 WARN 11168 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42809
2019-02-17 11:07:41.291 ERROR 11168 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: p_raise_wage_employee_older_than(integer, integer) is a procedure
Hinweis: To call a procedure, use CALL.
Position: 15
第一个 Hibernate 日志表明 Hibernate 使用 call 来执行存储过程,但我得到一个 SQL 异常,即未使用 CALL.这是 Postgresql 11 之前的 Postgresql 方言中的错误吗?您可以将 FUNCTIONS 建模为 JPA 中的存储过程,因此使用了 SELECT 而不是 CALL?
The first Hibernate log is indicating that Hibernate uses call to execute the stored procedure but I am getting a SQL exception that CALL is not used. Is this a bug in the Postgresql dialect as previous to Postgresql 11 you were able to model the FUNCTIONS as stored procedures within JPA and therefore SELECT was used and not CALL?
推荐答案
由于 pgJDBC 42.2.5 是在 PostgreSQL 11 版本(2018 年 10 月)之前(2018 年 8 月)发布的,我认为这是目前内部的一个问题PostgreSQL 本身的 JDBC 驱动程序.我在 GitHub 存储库中创建了一个 问题.
As the pgJDBC 42.2.5 was released prior (Aug, 2018) to the PostgreSQL 11 release (Oct, 2018), I think this is currently a issue within the JDBC driver for PostgreSQL itself. I've created a issue within the GitHub repository.
对于解决方法,您可以将 STORED PROCEDURE 重写为 FUNCTION 并使用 @NamedStoredProcedureQuery 或直接与 JDBC 交互CallableStatement 例如:
For a workaround, you could rewrite the STORED PROCEDURE as a FUNCTION and use @NamedStoredProcedureQuery or directly interact with the JDBC CallableStatement e.g.:
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/", "postgres", "postgres");
CallableStatement callableStatement = conn.prepareCall("{call f_raise_wage_employee_older_than(?,?)}");
callableStatement.setInt(1, 20);
callableStatement.setInt(2, 500);
callableStatement.executeUpdate();
或使用 EntityManager 执行本机查询:
Or execute a native query with the EntityManager:
this.em.createNativeQuery("CALL p_raise_wage_employee_older_than(1, 20)");
我会在收到 pgJDBC 维护者的答复后立即更新此答案.
I'll update this answer as soon as I get an answer from the pgJDBC maintainer.
更新:
Postgres 邮件列表(https://www.postgresql.org/message-id/4285.1537201440%40sss.pgh.pa.us)目前没有解决方案.唯一的方法是将本地 SQL 查询传递给数据库或将 STORED PROCEDURE 重写为 FUNCTION
This topic is already discussed in the Postgres Mailing list (https://www.postgresql.org/message-id/4285.1537201440%40sss.pgh.pa.us) and there is currently no solution. The only way is to pass native SQL queries to the database or rewrite the STORED PROCEDURE as a FUNCTION
这篇关于不能用Hibernate调用PostgreSQL的11个存储过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:不能用Hibernate调用PostgreSQL的11个存储过程
- 如何使用WebFilter实现授权头检查 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- C++ 和 Java 进程之间的共享内存 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
