PostgreSQL 11现在支持存储过程,我正在尝试使用Hibernate 5.3.7.Final和Postgresql 42.2.5 JDBC驱动程序调用存储过程。在PostgreSQL 11之前,我们使用JPA的@NamedStoredProcedure调用函数。然而,这些函数是通过SELECT my_func();执行的,而新的存储过程必须通过CALL my_procedure();执行。我正在尝试执行以下简单的存储过程:
第一条Hibernate日志表明Hibernate使用
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方言中的一个错误吗?因为在Postgresql 11之前,您可以将FUNCTIONS
建模为JPA中的存储过程,因此使用的是SELECT
而不是CALL
。
CALL
语法。您在日志中看到的{call ...}
语法是JDBC特定的语法,应该由JDBC驱动程序转换为适当的语法。您可能希望将此问题发布在此处,因为我在那里没有看到任何相关问题。--暂时,您可以使用“旧”的方法(即使用RETURNS VOID
定义FUNCTION
)。 - pozs