DATAJPA-1579 - Support multiple out parameters with nullable output data ad hoc stored procedure.
Original pull request: #390.
This commit is contained in:
committed by
Jens Schauder
parent
9c1e0ba645
commit
99d537402b
@@ -28,6 +28,7 @@ import javax.persistence.ParameterMode;
|
||||
import javax.persistence.StoredProcedureQuery;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -41,6 +42,7 @@ import java.util.stream.IntStream;
|
||||
* @author Jens Schauder
|
||||
* @author Mark Paluch
|
||||
* @author Jeff Sheets
|
||||
* @author JyotirmoyVS
|
||||
* @since 1.6
|
||||
*/
|
||||
class StoredProcedureJpaQuery extends AbstractJpaQuery {
|
||||
@@ -110,7 +112,7 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery {
|
||||
*
|
||||
* @param storedProcedureQuery must not be {@literal null}.
|
||||
* <p>
|
||||
* Result is either a single value, or a Map<String, Object> of output parameter names to values
|
||||
* Result is either a single value, or a Map<String, Optional<Object>> of output parameter names to nullable values
|
||||
*/
|
||||
@Nullable
|
||||
Object extractOutputValue(StoredProcedureQuery storedProcedureQuery) {
|
||||
@@ -121,21 +123,21 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> outputValues = IntStream.range(0, procedureAttributes.getOutputParameterNames().size()) //
|
||||
Map<String, Optional<Object>> outputValues = IntStream.range(0, procedureAttributes.getOutputParameterNames().size()) //
|
||||
.boxed() //
|
||||
.collect(Collectors.toMap( //
|
||||
procedureAttributes.getOutputParameterNames()::get, //
|
||||
i -> extractOutputParameter(storedProcedureQuery, i)));
|
||||
|
||||
return outputValues.size() == 1 ? outputValues.values().iterator().next() : outputValues;
|
||||
return outputValues.size() == 1 ? outputValues.values().iterator().next().orElse(null) : outputValues;
|
||||
}
|
||||
|
||||
private Object extractOutputParameter(StoredProcedureQuery storedProcedureQuery, Integer index) {
|
||||
private Optional<Object> extractOutputParameter(StoredProcedureQuery storedProcedureQuery, Integer index) {
|
||||
|
||||
String outputParameterName = procedureAttributes.getOutputParameterNames().get(index);
|
||||
JpaParameters parameters = getQueryMethod().getParameters();
|
||||
|
||||
return extractOutputParameterValue(storedProcedureQuery, outputParameterName, index, parameters.getNumberOfParameters());
|
||||
return Optional.ofNullable(extractOutputParameterValue(storedProcedureQuery, outputParameterName, index, parameters.getNumberOfParameters()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,6 +59,7 @@ import javax.persistence.TemporalType;
|
||||
* @author Christoph Strobl
|
||||
* @author Jens Schauder
|
||||
* @author Jeff Sheets
|
||||
* @author JyotirmoyVS
|
||||
*/
|
||||
@Entity
|
||||
@NamedEntityGraphs({ @NamedEntityGraph(name = "User.overview", attributeNodes = { @NamedAttributeNode("roles") }),
|
||||
@@ -97,7 +98,11 @@ import javax.persistence.TemporalType;
|
||||
@NamedStoredProcedureQuery(name = "User.plus1IO2", procedureName = "plus1inout2",
|
||||
parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
|
||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class),
|
||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res2", type = Integer.class) }) //
|
||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res2", type = Integer.class) }), //
|
||||
@NamedStoredProcedureQuery(name = "User.plus1IOoptional", procedureName = "plus1inoutoptional",
|
||||
parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
|
||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res", type = Integer.class),
|
||||
@StoredProcedureParameter(mode = ParameterMode.OUT, name = "res2", type = Integer.class) }) // DATAJPA-1579
|
||||
})
|
||||
@NamedStoredProcedureQuery(name = "User.plus1IO", procedureName = "plus1inout",
|
||||
parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "arg", type = Integer.class),
|
||||
|
||||
@@ -29,6 +29,7 @@ import javax.persistence.ParameterMode;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.StoredProcedureQuery;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
@@ -39,6 +40,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
* @author Oliver Gierke
|
||||
* @author Jeff Sheets
|
||||
* @author Jens Schauder
|
||||
* @author JyotirmoyVS
|
||||
* @since 1.6
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -90,12 +92,20 @@ public class UserRepositoryStoredProcedureIntegrationTests {
|
||||
assertThat(repository.entityAnnotatedCustomNamedProcedurePlus1IO2TwoOutParamsButNamingOne(1)).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test // DATAJPA-707
|
||||
@Test // DATAJPA-707 DATAJPA-1579
|
||||
public void entityAnnotatedCustomNamedProcedurePlus1IO2() {
|
||||
|
||||
Map<String, Integer> result = repository.entityAnnotatedCustomNamedProcedurePlus1IO2(1);
|
||||
Map<String, Optional<Integer>> result = repository.entityAnnotatedCustomNamedProcedurePlus1IO2(1);
|
||||
|
||||
assertThat(result).containsExactly(entry("res", 2), entry("res2", 3));
|
||||
assertThat(result).containsExactly(entry("res", Optional.of(2)), entry("res2", Optional.of(3)));
|
||||
}
|
||||
|
||||
@Test // DATAJPA-1579
|
||||
public void entityAnnotatedCustomNamedProcedurePlus1IOoptional() {
|
||||
|
||||
Map<String, java.util.Optional<Integer>> result = repository.entityAnnotatedCustomNamedProcedurePlus1IOoptional(1);
|
||||
|
||||
assertThat(result).containsExactly(entry("res", Optional.of(2)), entry("res2", Optional.empty()));
|
||||
}
|
||||
|
||||
@Test // DATAJPA-455
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.google.common.base.Optional;
|
||||
* @author Kevin Peters
|
||||
* @author Jeff Sheets
|
||||
* @author Andrey Kovalev
|
||||
* @author JyotirmoyVS
|
||||
*/
|
||||
public interface UserRepository
|
||||
extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User>, UserRepositoryCustom {
|
||||
@@ -351,8 +352,15 @@ public interface UserRepository
|
||||
* Explicitly mapped to named stored procedure "User.plus1IO2" in {@link EntityManager}.
|
||||
* Returns 2 out params as a Map.
|
||||
*/
|
||||
@Procedure(name = "User.plus1IO2") // DATAJPA-707
|
||||
Map<String, Integer> entityAnnotatedCustomNamedProcedurePlus1IO2(@Param("arg") Integer arg);
|
||||
@Procedure(name = "User.plus1IO2") // DATAJPA-707 DATAJPA-1579
|
||||
Map<String, java.util.Optional<Integer>> entityAnnotatedCustomNamedProcedurePlus1IO2(@Param("arg") Integer arg);
|
||||
|
||||
/**
|
||||
* Explicitly mapped to named stored procedure "User.plus1IOoptional" in {@link EntityManager}.
|
||||
* Returns 2 out params as a Map, second one amoung which is null.
|
||||
*/
|
||||
@Procedure(name = "User.plus1IOoptional") // DATAJPA-1579
|
||||
Map<String, java.util.Optional<Integer>> entityAnnotatedCustomNamedProcedurePlus1IOoptional(@Param("arg") Integer arg);
|
||||
|
||||
/**
|
||||
* Implicitly mapped to named stored procedure "User.plus1" in {@link EntityManager}.
|
||||
|
||||
@@ -14,6 +14,13 @@ BEGIN ATOMIC
|
||||
set res2 = arg + 2;
|
||||
END
|
||||
/;
|
||||
DROP procedure IF EXISTS plus1inoutoptional
|
||||
/;
|
||||
CREATE procedure plus1inoutoptional (IN arg int, OUT res int, OUT res2 int)
|
||||
BEGIN ATOMIC
|
||||
set res = arg + 1;
|
||||
END
|
||||
/;
|
||||
DROP procedure IF EXISTS procedure_in1_out1
|
||||
/;
|
||||
DROP procedure IF EXISTS procedure_in1_out0
|
||||
|
||||
Reference in New Issue
Block a user