diff --git a/pom.xml b/pom.xml index b62259838..56389ab45 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -101,7 +102,9 @@ - ${project.build.directory}/${project.artifactId}-${project.version}.zip + + ${project.build.directory}/${project.artifactId}-${project.version}.zip + zip @@ -358,7 +361,10 @@ **/OpenJpa* **/EclipseLink* - -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile} + + -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar + -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile} + @@ -371,7 +377,11 @@ **/EclipseLink*Tests.java - -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile} -javaagent:${settings.localRepository}/org/eclipse/persistence/org.eclipse.persistence.jpa/${eclipselink}/org.eclipse.persistence.jpa-${eclipselink}.jar -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar + + -javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile} + -javaagent:${settings.localRepository}/org/eclipse/persistence/org.eclipse.persistence.jpa/${eclipselink}/org.eclipse.persistence.jpa-${eclipselink}.jar + -javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar + diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java index ac09f871d..cb2bc61b4 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java @@ -54,6 +54,7 @@ import org.springframework.util.ReflectionUtils; * @author Nicolas Cirigliano * @author Jens Schauder * @author Gabriel Basilio + * @author Greg Turnquist */ public abstract class JpaQueryExecution { @@ -319,19 +320,16 @@ public abstract class JpaQueryExecution { boolean returnsResultSet = storedProcedure.execute(); if (returnsResultSet) { - if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) + + if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) { throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION); - - List result = storedProcedure.getResultList(); - - if (!storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) { - if (result.isEmpty()) - return null; - if (result.size() == 1) - return result.get(0); } - return result; + if (storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) { + return storedProcedure.getResultList(); + } else { + return storedProcedure.getSingleResult(); + } } return storedProcedureJpaQuery.extractOutputValue(storedProcedure); diff --git a/src/main/java/org/springframework/data/jpa/repository/query/Procedure.java b/src/main/java/org/springframework/data/jpa/repository/query/Procedure.java index 13007cc25..7b7835152 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/Procedure.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/Procedure.java @@ -54,7 +54,7 @@ public @interface Procedure { String outputParameterName() default ""; /** - * Whether the procedure returns a Ref Cursor from the database {@code false}. + * Whether the procedure returns a Ref Cursor from the database - defaults to {@code false}. */ boolean refCursor() default false; } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ProcedureParameter.java b/src/main/java/org/springframework/data/jpa/repository/query/ProcedureParameter.java index 6d185e502..77577fc43 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ProcedureParameter.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ProcedureParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2020 the original author or authors. + * Copyright 2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +16,27 @@ package org.springframework.data.jpa.repository.query; -import org.springframework.lang.Nullable; +import java.util.Objects; import javax.persistence.ParameterMode; +import org.springframework.lang.Nullable; + /** - * This class represents a Stored Procedure Parameter - * and an instance of the annotation {@link javax.persistence.StoredProcedureParameter}. + * This class represents a Stored Procedure Parameter and an instance of the annotation + * {@link javax.persistence.StoredProcedureParameter}. * * @author Gabriel Basilio + * @author Greg Turnquist */ -public class ProcedureParameter { +class ProcedureParameter { private final String name; private final ParameterMode mode; private final Class type; - public ProcedureParameter(@Nullable String name, ParameterMode mode, Class type) { + ProcedureParameter(@Nullable String name, ParameterMode mode, Class type) { + this.name = name; this.mode = mode; this.type = type; @@ -49,4 +53,29 @@ public class ProcedureParameter { public Class getType() { return type; } -} \ No newline at end of file + + @Override + public boolean equals(Object o) { + + if (this == o) { + return true; + } + + if (!(o instanceof ProcedureParameter)) { + return false; + } + + ProcedureParameter that = (ProcedureParameter) o; + return Objects.equals(name, that.name) && mode == that.mode && Objects.equals(type, that.type); + } + + @Override + public int hashCode() { + return Objects.hash(name, mode, type); + } + + @Override + public String toString() { + return "ProcedureParameter{" + "name='" + name + '\'' + ", mode=" + mode + ", type=" + type + '}'; + } +} diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java index 0160ad65e..010ceb38f 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java @@ -18,7 +18,9 @@ package org.springframework.data.jpa.repository.query; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.persistence.NamedStoredProcedureQueries; import javax.persistence.NamedStoredProcedureQuery; @@ -28,6 +30,7 @@ import javax.persistence.StoredProcedureParameter; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -40,6 +43,7 @@ import org.springframework.util.StringUtils; * @author Diego Diez * @author Jeff Sheets * @author Gabriel Basilio + * @author Greg Turnquist * @since 1.6 */ enum StoredProcedureAttributeSource { @@ -69,9 +73,9 @@ enum StoredProcedureAttributeSource { } String procedureName = deriveProcedureNameFrom(method, procedure); - if (StringUtils.isEmpty(procedureName)) { - throw new IllegalArgumentException("Could not determine name of procedure for @Procedure annotated method: " - + method); + if (ObjectUtils.isEmpty(procedureName)) { + throw new IllegalArgumentException( + "Could not determine name of procedure for @Procedure annotated method: " + method); } return new StoredProcedureAttributes(procedureName, createOutputProcedureParameterFrom(method, procedure)); @@ -96,42 +100,57 @@ enum StoredProcedureAttributeSource { } /** + * Extract procedure attributes from method and procedure. + * * @param method * @param namedStoredProc * @param procedure * @return */ - private StoredProcedureAttributes newProcedureAttributesFrom(Method method, - NamedStoredProcedureQuery namedStoredProc, Procedure procedure) { + private StoredProcedureAttributes newProcedureAttributesFrom(Method method, NamedStoredProcedureQuery namedStoredProc, + Procedure procedure) { - List outputParameters = new ArrayList<>(); + List outputParameters; if (!procedure.outputParameterName().isEmpty()) { + // we give the output parameter definition from the @Procedure annotation precedence - outputParameters.add(createOutputProcedureParameterFrom(method, procedure)); + outputParameters = Collections.singletonList(createOutputProcedureParameterFrom(method, procedure)); } else { // try to discover the output parameter - List namedProcedureOutputParameters = extractOutputParametersFrom(namedStoredProc); - - for (StoredProcedureParameter outputParameter : namedProcedureOutputParameters) { - outputParameters.add(new ProcedureParameter( - outputParameter.name(), outputParameter.mode(), outputParameter.type())); - } + outputParameters = extractOutputParametersFrom(namedStoredProc).stream() // + .map(namedParameter -> new ProcedureParameter(namedParameter.name(), namedParameter.mode(), + namedParameter.type())) // + .collect(Collectors.toList()); } return new StoredProcedureAttributes(namedStoredProc.name(), outputParameters, true); } + /** + * Create a {@link ProcedureParameter} from relevant {@link Method} and {@link Procedure}. + * + * @param method + * @param procedure + * @return + */ private ProcedureParameter createOutputProcedureParameterFrom(Method method, Procedure procedure) { + return new ProcedureParameter(procedure.outputParameterName(), - procedure.refCursor() ? ParameterMode.REF_CURSOR : ParameterMode.OUT, - method.getReturnType()); + procedure.refCursor() ? ParameterMode.REF_CURSOR : ParameterMode.OUT, method.getReturnType()); } + /** + * Translate all the {@Link NamedStoredProcedureQuery} parameters into a {@link List} of + * {@link StoredProcedureParameter}s. + * + * @param namedStoredProc + * @return + */ private List extractOutputParametersFrom(NamedStoredProcedureQuery namedStoredProc) { - List outputParameters = new ArrayList(); + List outputParameters = new ArrayList<>(); for (StoredProcedureParameter param : namedStoredProc.parameters()) { @@ -190,9 +209,12 @@ enum StoredProcedureAttributeSource { * @param procedure * @return */ - private String derivedNamedProcedureNameFrom(Method method, JpaEntityMetadata entityMetadata, Procedure procedure) { - return StringUtils.hasText(procedure.name()) ? procedure.name() : entityMetadata.getEntityName() + "." - + method.getName(); + private String derivedNamedProcedureNameFrom(Method method, JpaEntityMetadata entityMetadata, + Procedure procedure) { + + return StringUtils.hasText(procedure.name()) // + ? procedure.name() // + : entityMetadata.getEntityName() + "." + method.getName(); } /** @@ -201,7 +223,7 @@ enum StoredProcedureAttributeSource { */ private List collectNamedStoredProcedureQueriesFrom(Class entityType) { - List queries = new ArrayList(); + List queries = new ArrayList<>(); NamedStoredProcedureQueries namedQueriesAnnotation = AnnotatedElementUtils.findMergedAnnotation(entityType, NamedStoredProcedureQueries.class); diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributes.java b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributes.java index 7c885fc13..fc89d2dc5 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributes.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributes.java @@ -15,16 +15,16 @@ */ package org.springframework.data.jpa.repository.query; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -import javax.persistence.StoredProcedureQuery; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; +import javax.persistence.StoredProcedureQuery; + +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + /** * Stored procedure configuration for JPA 2.1 {@link StoredProcedureQuery}s. * @@ -48,7 +48,7 @@ class StoredProcedureAttributes { /** * Creates a new {@link StoredProcedureAttributes}. * - * @param procedureName must not be {@literal null}. + * @param procedureName must not be {@literal null}. */ StoredProcedureAttributes(String procedureName, ProcedureParameter parameter) { this(procedureName, Collections.singletonList(parameter), false); @@ -57,14 +57,16 @@ class StoredProcedureAttributes { /** * Creates a new {@link StoredProcedureAttributes}. * - * @param procedureName must not be {@literal null}. + * @param procedureName must not be {@literal null}. * @param namedStoredProcedure flag signaling if the stored procedure has a name. */ - StoredProcedureAttributes(String procedureName, List outputProcedureParameters, boolean namedStoredProcedure) { + StoredProcedureAttributes(String procedureName, List outputProcedureParameters, + boolean namedStoredProcedure) { Assert.notNull(procedureName, "ProcedureName must not be null!"); Assert.notNull(outputProcedureParameters, "OutputProcedureParameters must not be null!"); - Assert.isTrue(outputProcedureParameters.size() != 1 || outputProcedureParameters.get(0) != null, "ProcedureParameters must not have size 1 with a null value"); + Assert.isTrue(outputProcedureParameters.size() != 1 || outputProcedureParameters.get(0) != null, + "ProcedureParameters must not have size 1 with a null value"); this.procedureName = procedureName; this.namedStoredProcedure = namedStoredProcedure; @@ -77,15 +79,16 @@ class StoredProcedureAttributes { } private List getParametersWithCompletedNames(List procedureParameters) { - return IntStream.range(0, procedureParameters.size()) - .mapToObj(i -> getParameterWithCompletedName(procedureParameters.get(i), i)) + + return IntStream.range(0, procedureParameters.size()) // + .mapToObj(i -> getParameterWithCompletedName(procedureParameters.get(i), i)) // .collect(Collectors.toList()); } private ProcedureParameter getParameterWithCompletedName(ProcedureParameter parameter, int i) { - return new ProcedureParameter( - completeOutputParameterName(i, parameter.getName()), - parameter.getMode(), parameter.getType()); + + return new ProcedureParameter(completeOutputParameterName(i, parameter.getName()), parameter.getMode(), + parameter.getType()); } private String completeOutputParameterName(int i, String paramName) { @@ -130,6 +133,7 @@ class StoredProcedureAttributes { * @return */ public boolean hasReturnValue() { + if (getOutputProcedureParameters().isEmpty()) return false; diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java index caacc7adc..9aadb5c4c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java @@ -18,20 +18,16 @@ package org.springframework.data.jpa.repository.query; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.IntStream; import javax.persistence.EntityManager; import javax.persistence.NamedStoredProcedureQuery; import javax.persistence.ParameterMode; -import javax.persistence.StoredProcedureParameter; import javax.persistence.StoredProcedureQuery; import javax.persistence.TypedQuery; import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter; import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.ResultProcessor; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -143,7 +139,8 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { for (int i = 0; i < outputParameters.size(); i++) { ProcedureParameter outputParameter = outputParameters.get(i); - outputValues.put(outputParameter.getName(), extractOutputParameterValue(outputParameter, i, storedProcedureQuery)); + outputValues.put(outputParameter.getName(), + extractOutputParameterValue(outputParameter, i, storedProcedureQuery)); } return outputValues; @@ -152,12 +149,13 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { /** * @return The value of an output parameter either by name or by index. */ - private Object extractOutputParameterValue(ProcedureParameter outputParameter, Integer index, StoredProcedureQuery storedProcedureQuery) { + private Object extractOutputParameterValue(ProcedureParameter outputParameter, Integer index, + StoredProcedureQuery storedProcedureQuery) { JpaParameters methodParameters = getQueryMethod().getParameters(); - return useNamedParameters && StringUtils.hasText(outputParameter.getName()) ? - storedProcedureQuery.getOutputParameterValue(outputParameter.getName()) + return useNamedParameters && StringUtils.hasText(outputParameter.getName()) + ? storedProcedureQuery.getOutputParameterValue(outputParameter.getName()) : storedProcedureQuery.getOutputParameterValue(methodParameters.getNumberOfParameters() + index + 1); } @@ -166,7 +164,8 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { */ private StoredProcedureQuery createStoredProcedure() { - return procedureAttributes.isNamedStoredProcedure() ? newNamedStoredProcedureQuery() + return procedureAttributes.isNamedStoredProcedure() // + ? newNamedStoredProcedureQuery() : newAdhocStoredProcedureQuery(); } @@ -205,15 +204,20 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { ProcedureParameter procedureOutput = procedureAttributes.getOutputProcedureParameters().get(0); - /* If the stored procedure returns a ResultSet without using REF_CURSOR, - it is not necessary to declare an output parameter */ - if ((isResultSetProcedure() && procedureOutput.getMode() == ParameterMode.REF_CURSOR) || !isResultSetProcedure()) { + /** + * If there is a {@link java.sql.ResultSet} with a {@link ParameterMode#REF_CURSOR}, find the output parameter. + * Otherwise, no need, there is no need to find an output parameter. + */ + if (storedProcedureHasResultSetUsingRefCursor(procedureOutput) || !isResultSetProcedure()) { if (useNamedParameters) { - procedureQuery.registerStoredProcedureParameter(procedureOutput.getName(), procedureOutput.getType(), procedureOutput.getMode()); + procedureQuery.registerStoredProcedureParameter(procedureOutput.getName(), procedureOutput.getType(), + procedureOutput.getMode()); } else { + // Output parameter should be after the input parameters int outputParameterIndex = params.getNumberOfParameters() + 1; + procedureQuery.registerStoredProcedureParameter(outputParameterIndex, procedureOutput.getType(), procedureOutput.getMode()); } @@ -223,18 +227,29 @@ class StoredProcedureJpaQuery extends AbstractJpaQuery { return procedureQuery; } + /** + * Does this stored procedure has a {@link java.sql.ResultSet} using {@link ParameterMode#REF_CURSOR}? + * + * @param procedureOutput + * @return + */ + private boolean storedProcedureHasResultSetUsingRefCursor(ProcedureParameter procedureOutput) { + return isResultSetProcedure() && procedureOutput.getMode() == ParameterMode.REF_CURSOR; + } + private StoredProcedureQuery createAdhocStoredProcedureQuery() { - String procedureName = procedureAttributes.getProcedureName(); if (getQueryMethod().isQueryForEntity()) { - return getEntityManager().createStoredProcedureQuery(procedureName, + + return getEntityManager().createStoredProcedureQuery(procedureAttributes.getProcedureName(), getQueryMethod().getEntityInformation().getJavaType()); } - return getEntityManager().createStoredProcedureQuery(procedureName); + return getEntityManager().createStoredProcedureQuery(procedureAttributes.getProcedureName()); } /** + * * @return true if the stored procedure will use a ResultSet to return data and not output parameters */ private boolean isResultSetProcedure() { diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java index 4147b1860..d4773baab 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java @@ -69,6 +69,8 @@ import com.querydsl.core.types.EntityPath; * @author Jens Schauder * @author Stefan Fussenegger * @author Réda Housni Alaoui + * @author Gabriel Basilio + * @author Greg Turnquist */ public class JpaRepositoryFactory extends RepositoryFactorySupport { @@ -214,6 +216,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport { @Override protected Optional getQueryLookupStrategy(@Nullable Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { + return Optional.of(JpaQueryLookupStrategy.create(entityManager, queryMethodFactory, key, evaluationContextProvider, escapeCharacter)); } diff --git a/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java index c02dc7f1c..11bf21f1e 100644 --- a/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/StoredProcedureIntegrationTests.java @@ -28,7 +28,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java index caf306b16..d4388f025 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSourceUnitTests.java @@ -50,6 +50,7 @@ import org.springframework.util.ReflectionUtils; * @author Jeff Sheets * @author Jens Schauder * @author Gabriel Basilio + * @author Greg Turnquist * @since 1.6 */ @ExtendWith(MockitoExtension.class) @@ -72,7 +73,9 @@ class StoredProcedureAttributeSourceUnitTests { void shouldCreateStoredProcedureAttributesFromProcedureMethodWithImplicitProcedureName() { StoredProcedureAttributes attr = creator.createFrom(method("plus1inout", Integer.class), entityMetadata); + ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -86,6 +89,7 @@ class StoredProcedureAttributeSourceUnitTests { entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -99,6 +103,7 @@ class StoredProcedureAttributeSourceUnitTests { entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -112,6 +117,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("explicitPlus1inoutViaProcedureNameAlias", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -125,6 +131,7 @@ class StoredProcedureAttributeSourceUnitTests { method("explicitPlus1inoutViaProcedureNameAliasAndOutputParameterName", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -138,6 +145,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("entityAnnotatedCustomNamedProcedurePlus1IO", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("User.plus1IO"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -151,6 +159,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("entityAnnotatedCustomNamedProcedureOutputParamNamePlus1IO", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("User.plus1IO"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -183,6 +192,7 @@ class StoredProcedureAttributeSourceUnitTests { StoredProcedureAttributes attr = creator.createFrom(method("plus1", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("User.plus1"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -196,6 +206,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("plus1inoutWithComposedAnnotationOverridingProcedureName", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("plus1inout"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -209,6 +220,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("plus1inoutWithComposedAnnotationOverridingName", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("User.plus1"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Integer.class); @@ -222,6 +234,7 @@ class StoredProcedureAttributeSourceUnitTests { entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("0_input_1_row_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Dummy.class); @@ -235,6 +248,7 @@ class StoredProcedureAttributeSourceUnitTests { entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("1_input_1_row_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(Dummy.class); @@ -247,6 +261,7 @@ class StoredProcedureAttributeSourceUnitTests { StoredProcedureAttributes attr = creator.createFrom(method("entityListFromResultSetWithNoInput"), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("0_input_1_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(List.class); @@ -261,6 +276,7 @@ class StoredProcedureAttributeSourceUnitTests { entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("1_input_1_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(List.class); @@ -274,6 +290,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("genericObjectListFromResultSetWithInput", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("1_input_1_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(List.class); @@ -287,6 +304,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("entityListFromResultSetWithInputAndNamedOutput", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("1_input_1_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.OUT); assertThat(outputParameter.getType()).isEqualTo(List.class); @@ -300,6 +318,7 @@ class StoredProcedureAttributeSourceUnitTests { .createFrom(method("entityListFromResultSetWithInputAndNamedOutputAndCursor", Integer.class), entityMetadata); ProcedureParameter outputParameter = attr.getOutputProcedureParameters().get(0); + assertThat(attr.getProcedureName()).isEqualTo("1_input_1_resultset"); assertThat(outputParameter.getMode()).isEqualTo(ParameterMode.REF_CURSOR); assertThat(outputParameter.getType()).isEqualTo(List.class); @@ -319,58 +338,50 @@ class StoredProcedureAttributeSourceUnitTests { /** * Explicitly mapped to a procedure with name "plus1inout" in database. */ - @Procedure("plus1inout") - // DATAJPA-455 + @Procedure("plus1inout") // DATAJPA-455 Integer explicitlyNamedPlus1inout(Integer arg); /** * Explicitly mapped to a procedure with name "plus1inout" in database via alias. */ - @Procedure(procedureName = "plus1inout") - // DATAJPA-455 + @Procedure(procedureName = "plus1inout") // DATAJPA-455 Integer explicitPlus1inoutViaProcedureNameAlias(Integer arg); /** - * Explicitly mapped to a procedure with name "plus1inout" in database via alias and explicitly named ouput + * Explicitly mapped to a procedure with name "plus1inout" in database via alias and explicitly named output * parameter. */ - @Procedure(procedureName = "plus1inout", outputParameterName = "res") - // DATAJPA-1297 + @Procedure(procedureName = "plus1inout", outputParameterName = "res") // DATAJPA-1297 Integer explicitPlus1inoutViaProcedureNameAliasAndOutputParameterName(Integer arg); /** * Implicitly mapped to a procedure with name "plus1inout" in database via alias. */ - @Procedure - // DATAJPA-455 + @Procedure // DATAJPA-455 Integer plus1inout(Integer arg); /** * Explicitly mapped to named stored procedure "User.plus1IO" in {@link EntityManager}. */ - @Procedure(name = "User.plus1IO") - // DATAJPA-455 + @Procedure(name = "User.plus1IO") // DATAJPA-455 Integer entityAnnotatedCustomNamedProcedurePlus1IO(@Param("arg") Integer arg); /** - * Explicitly mapped to named stored procedure "User.plus1IO" in {@link EntityManager}. With a outputParameterName + * Explicitly mapped to named stored procedure "User.plus1IO" in {@link EntityManager} with an outputParameterName. */ - @Procedure(name = "User.plus1IO", outputParameterName = "override") - // DATAJPA-707 + @Procedure(name = "User.plus1IO", outputParameterName = "override") // DATAJPA-707 Integer entityAnnotatedCustomNamedProcedureOutputParamNamePlus1IO(@Param("arg") Integer arg); /** * Explicitly mapped to named stored procedure "User.plus1IO2" in {@link EntityManager}. */ - @Procedure(name = "User.plus1IO2") - // DATAJPA-707 + @Procedure(name = "User.plus1IO2") // DATAJPA-707 Map entityAnnotatedCustomNamedProcedurePlus1IO2(@Param("arg") Integer arg); /** * Implicitly mapped to named stored procedure "User.plus1" in {@link EntityManager}. */ - @Procedure - // DATAJPA-455 + @Procedure // DATAJPA-455 Integer plus1(@Param("arg") Integer arg); @ComposedProcedureUsingAliasFor(explicitProcedureName = "plus1inout") @@ -379,32 +390,25 @@ class StoredProcedureAttributeSourceUnitTests { @ComposedProcedureUsingAliasFor(emProcedureName = "User.plus1") Integer plus1inoutWithComposedAnnotationOverridingName(Integer arg); - @Procedure("0_input_1_row_resultset") - // DATAJPA-1657 + @Procedure("0_input_1_row_resultset") // DATAJPA-1657 Dummy singleEntityFrom1RowResultSetAndNoInput(); - @Procedure("1_input_1_row_resultset") - // DATAJPA-1657 + @Procedure("1_input_1_row_resultset") // DATAJPA-1657 Dummy singleEntityFrom1RowResultSetWithInput(Integer arg); - @Procedure("0_input_1_resultset") - // DATAJPA-1657 + @Procedure("0_input_1_resultset") // DATAJPA-1657 List entityListFromResultSetWithNoInput(); - @Procedure("1_input_1_resultset") - // DATAJPA-1657 + @Procedure("1_input_1_resultset") // DATAJPA-1657 List entityListFromResultSetWithInput(Integer arg); - @Procedure("1_input_1_resultset") - // DATAJPA-1657 + @Procedure("1_input_1_resultset") // DATAJPA-1657 List genericObjectListFromResultSetWithInput(Integer arg); - @Procedure(value = "1_input_1_resultset", outputParameterName = "dummies") - // DATAJPA-1657 + @Procedure(value = "1_input_1_resultset", outputParameterName = "dummies") // DATAJPA-1657 List entityListFromResultSetWithInputAndNamedOutput(Integer arg); - @Procedure(value = "1_input_1_resultset", outputParameterName = "dummies", refCursor = true) - // DATAJPA-1657 + @Procedure(value = "1_input_1_resultset", outputParameterName = "dummies", refCursor = true) // DATAJPA-1657 List entityListFromResultSetWithInputAndNamedOutputAndCursor(Integer arg); } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributesUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributesUnitTests.java index 3d1bedbbe..73a35ba0a 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributesUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributesUnitTests.java @@ -18,10 +18,10 @@ package org.springframework.data.jpa.repository.query; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.jpa.repository.query.StoredProcedureAttributes.*; -import org.junit.jupiter.api.Test; - import javax.persistence.ParameterMode; +import org.junit.jupiter.api.Test; + /** * Unit tests for {@link StoredProcedureAttributes}. * @@ -33,8 +33,8 @@ class StoredProcedureAttributesUnitTests { @Test // DATAJPA-681 void usesSyntheticOutputParameterNameForAdhocProcedureWithoutOutputName() { - ProcedureParameter outputParameter = new ProcedureParameter(null, ParameterMode.OUT, Long.class); - StoredProcedureAttributes attributes = new StoredProcedureAttributes("procedure", outputParameter); + StoredProcedureAttributes attributes = new StoredProcedureAttributes("procedure", + new ProcedureParameter(null, ParameterMode.OUT, Long.class)); assertThat(attributes.getOutputProcedureParameters().get(0).getName()).isEqualTo(SYNTHETIC_OUTPUT_PARAMETER_NAME); } }