From b4b41eb1bfe39d9b7e46df755e8cf09af2fbdc64 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 21 Oct 2024 14:50:12 +0200 Subject: [PATCH] Fix named procedure return value retrieval for named procedures. We assume that if a stored procedure is named (associated with the Persitence Context) that we can access its out values by name. Closes #1759 --- .../query/StoredProcedureJpaQuery.java | 20 ++++++++++++------- ...stgresStoredProcedureIntegrationTests.java | 9 ++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java index e9353b83e..54d6b0b24 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java @@ -15,16 +15,16 @@ */ package org.springframework.data.jpa.repository.query; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import jakarta.persistence.EntityManager; import jakarta.persistence.NamedStoredProcedureQuery; import jakarta.persistence.ParameterMode; import jakarta.persistence.StoredProcedureQuery; import jakarta.persistence.TypedQuery; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.QueryMethod; @@ -138,11 +138,17 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { * @return The value of an output parameter either by name or by index. */ private Object extractOutputParameterValue(ProcedureParameter outputParameter, - StoredProcedureQuery storedProcedureQuery) { + StoredProcedureQuery query) { + + if (procedureAttributes.isNamedStoredProcedure() && StringUtils.hasText(outputParameter.getName())) { + + return StringUtils.hasText(outputParameter.getName()) ? query.getOutputParameterValue(outputParameter.getName()) + : query.getOutputParameterValue(outputParameter.getPosition()); + } return useNamedParameters && StringUtils.hasText(outputParameter.getName()) - ? storedProcedureQuery.getOutputParameterValue(outputParameter.getName()) - : storedProcedureQuery.getOutputParameterValue(outputParameter.getPosition()); + ? query.getOutputParameterValue(outputParameter.getName()) + : query.getOutputParameterValue(outputParameter.getPosition()); } /** diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java index 1be3894a9..02e52f9d1 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/procedures/PostgresStoredProcedureIntegrationTests.java @@ -16,7 +16,7 @@ package org.springframework.data.jpa.repository.procedures; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import jakarta.persistence.Entity; import jakarta.persistence.EntityManagerFactory; @@ -38,6 +38,7 @@ import org.hibernate.dialect.PostgreSQLDialect; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.postgresql.ds.PGSimpleDataSource; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan.Filter; @@ -58,6 +59,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; + import org.testcontainers.containers.PostgreSQLContainer; /** @@ -165,6 +167,11 @@ class PostgresStoredProcedureIntegrationTests { procedureName = "get_employees", // parameters = { @StoredProcedureParameter(mode = ParameterMode.REF_CURSOR, type = void.class) }, // resultClasses = Employee.class) + + @NamedStoredProcedureQuery( // + name = "Employee.noResultSet", // + procedureName = "get_employees_count", // + parameters = { @StoredProcedureParameter(mode = ParameterMode.OUT, name = "results", type = Integer.class) }) @NamedStoredProcedureQuery( // name = "positional_inout", // procedureName = "positional_inout_parameter_issue3460", //