You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JPA调用PostgreSQL存储过程报错求助

PostgreSQL存储过程调用失败问题

已创建的存储过程

CREATE OR REPLACE PROCEDURE reset_disabled()  
LANGUAGE plpgsql  
AS $$
DECLARE
BEGIN  
UPDATE regional_price_info
       SET disabled = NULL;
END;  
$$; 

两种调用方式及报错情况

1. 使用@Query注解调用

代码:

@Query(value = "CALL reset_disabled();", nativeQuery = true)
void priceActivator();

报错信息:

org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet

2. 使用@Procedure注解调用

代码:

@Procedure(value = "reset_disabled")
void priceActivator2();

报错信息:

2023-02-22T07:43:00,013 [scheduling-1] [INFO ] com.zageno.pricing.activator.PriceActivator priceActivatorByValidity [28] - Triggering price activator procedure
Hibernate: {call reset_disabled()}
2023-02-22T07:43:00,016 [scheduling-1] [WARN ] org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions [137] - SQL Error: 0, SQLState: 42809
2023-02-22T07:43:00,017 [scheduling-1] [ERROR] org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions [142] - ERROR: reset_disabled() is a procedure
Hint: To call a procedure, use CALL.
Position: 15

这里Hibernate生成了{call reset_disabled()}的调用语句,但PostgreSQL报错要求用CALL,看似矛盾,实际是Hibernate的JDBC调用格式与PostgreSQL存储过程调用语法不兼容导致。

解决方法

方法1:修正@Query注解配置

存储过程执行的是UPDATE操作,无结果集返回,需添加@Modifying注解告知JPA无需提取结果集,同时确保调用处于事务环境中:

@Modifying
@Transactional
@Query(value = "CALL reset_disabled();", nativeQuery = true)
void priceActivator();

方法2:调整@Procedure注解及方言配置

指定正确的存储过程名称,并添加事务支持,同时配置Hibernate适配PostgreSQL方言:

@Transactional
@Procedure(procedureName = "reset_disabled")
void priceActivator2();

在配置文件中添加:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.proc.param_null_passing=true

方法3:通过EntityManager直接调用

绕过Spring Data的封装,直接用EntityManager执行存储过程:

@Autowired
EntityManager entityManager;

@Transactional
public void callResetDisabled() {
    entityManager.createNativeQuery("CALL reset_disabled()").executeUpdate();
}

原因解析

  • 第一种@Query报错:JPA默认期望查询返回结果集,但该存储过程仅执行更新操作,无结果集,需@Modifying注解标记为修改类操作。
  • 第二种@Procedure报错:Hibernate生成的{call ...}是JDBC标准调用格式,PostgreSQL对存储过程调用要求更严格,需直接使用CALL语句,配置正确方言或直接用EntityManager可解决该兼容性问题。

内容的提问来源于stack exchange,提问作者user1073214

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:39:21