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个存储过程
基础教程推荐
- 验证是否调用了所有 getter 方法 2022-01-01
- 不推荐使用 Api 注释的描述 2022-01-01
- Java Swing计时器未清除 2022-01-01
- Java 实例变量在两个语句中声明和初始化 2022-01-01
- 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
- 在 Java 中创建日期的正确方法是什么? 2022-01-01
- 多个组件的复杂布局 2022-01-01
- 大摇大摆的枚举 2022-01-01
- 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
- 从 python 访问 JVM 2022-01-01
