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
This commit is contained in:
Mark Paluch
2024-10-21 14:50:12 +02:00
parent 455d68d5a2
commit b4b41eb1bf
2 changed files with 21 additions and 8 deletions

View File

@@ -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());
}
/**

View File

@@ -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", //