【发布时间】:2019-07-10 22:43:27
【问题描述】:
PostgreSQL 11 现在支持存储过程,我正在尝试使用 Hibernate 5.3.7.Final 和 Postgresql 42.2.5 JDBC 驱动程序 调用一个。在 PostgreSQL 11 之前,我们有可以使用 JPA 的 @NamedStoredProcedure 调用的函数。但是,函数是用SELECT my_func(); 执行的,新的存储过程必须用CALL my_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 注释如下所示:
@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?
【问题讨论】:
-
你能使用一个基本的 JDBC CallableStatement 吗?建议您尝试一下,因为这可能是所有 JPA 提供程序都在使用的,所以它可以将问题隔离到不同之处
-
由于 pgJDBC 42.2.5 于 2018 年 8 月在 PostgreSQL 11(2018 年 10 月)之前发布,我怀疑其中是否支持
CALL语法。您在日志中看到的{call ...}语法是特定于 JDBC 的语法,它应该由 JDBC 驱动程序转换为适当的语法。您可能想发布此here,因为我在那里没有看到任何相关问题。 -- 目前,你可以使用“旧”方式(即用RETURNS VOID定义FUNCTIONs)。
标签: java postgresql hibernate jpa spring-data