如何使用 Spring JPA 调用存储过程(PostgreSQL)?

问题描述 投票:0回答:2

PostgreSQL 过程:

CREATE OR REPLACE PROCEDURE public.create_task_by_device(task_id integer, device_ids text)
 LANGUAGE plpgsql
AS $procedure$
    begin
        -- do something here
    END;
$procedure$
;

Spring JPA:(Kotlin)

interface TaskTemplateRepository : JpaRepository<TaskTemplate, Int> {
    @Procedure("public.create_task_by_device")
    fun createTaskByDevice(@Param("task_id") taskId: Int, @Param("device_ids") device_ids: String)
}

例外:

org.postgresql.util.PSQLException: ERROR: public.create_task_by_device(integer, character varying) is a procedure. To call a procedure, use CALL.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553) ~[postgresql-42.2.20.jar:42.2.20]

然后我就通过

{call public.create_task_by_device(?,?)}
执行了SQL语句
spring.jpa.show-sql: true

看来实际执行的语句是

call
使用call。

我不明白为什么整个句子都被

{ ... }

包围

然后尝试单步调试,

org.postgresql.jdbc.PgStatement#execute
方法中实际执行的SQL语句是
select * from create_task_by_device(1,'2') as result
,不像JPA在命令行输出的SQL语句,不知道为什么

最后我尝试写自己的SQL语句

    @Query("call public.create_task_by_device(?1, ?2)", nativeQuery = true)
    fun createTaskByDevice(@Param("task_id") taskId: Int, @Param("device_ids") device_ids: String)

我又遇到了一个异常

org.postgresql.util.PSQLException: No results were returned by the query.

如果我在方法中添加

@Modifying
,则会抛出
javax.persistence.TransactionRequiredException: Executing an update/delete query

spring postgresql spring-data-jpa spring-data
2个回答
3
投票

尝试将 : 作为占位符更改为 @Query -> (:task_id,:device_ids);

@Query(value = "{call public.create_task_by_device(:task_id,:device_ids)}",nativeQuery = true)

如果 SP 执行 DML 操作(如(Insert,Update)),请添加以下注释和 @Query;

@Transactional 
@Modifying(clearAutomatically = true)

这是参考 -> https://www.baeldung.com/spring-data-jpa-stored-procedures#query-annotation


0
投票

添加此注释将不会出现问题 @Transactional(propagation = Propagation.NOT_SUPPORTED)。它解决了我的问题,谢谢大家:-)

© www.soinside.com 2019 - 2024. All rights reserved.