Skip to content

Commit 0a81bc6

Browse files
committed
Polishing.
See: #1959, #409.
1 parent 554bd3d commit 0a81bc6

11 files changed

+193
-109
lines changed

Diff for: pom.xml

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
34

45
<modelVersion>4.0.0</modelVersion>
56

@@ -101,7 +102,9 @@
101102
<configuration>
102103
<artifacts>
103104
<artifact>
104-
<file>${project.build.directory}/${project.artifactId}-${project.version}.zip</file>
105+
<file>
106+
${project.build.directory}/${project.artifactId}-${project.version}.zip
107+
</file>
105108
<type>zip</type>
106109
</artifact>
107110
</artifacts>
@@ -358,7 +361,10 @@
358361
<exclude>**/OpenJpa*</exclude>
359362
<exclude>**/EclipseLink*</exclude>
360363
</excludes>
361-
<argLine>-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}</argLine>
364+
<argLine>
365+
-javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar
366+
-javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile}
367+
</argLine>
362368
</configuration>
363369
</execution>
364370
<execution>
@@ -371,7 +377,11 @@
371377
<includes>
372378
<include>**/EclipseLink*Tests.java</include>
373379
</includes>
374-
<argLine>-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</argLine>
380+
<argLine>
381+
-javaagent:${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco}/org.jacoco.agent-${jacoco}-runtime.jar=destfile=${jacoco.destfile}
382+
-javaagent:${settings.localRepository}/org/eclipse/persistence/org.eclipse.persistence.jpa/${eclipselink}/org.eclipse.persistence.jpa-${eclipselink}.jar
383+
-javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring}/spring-instrument-${spring}.jar
384+
</argLine>
375385
</configuration>
376386
</execution>
377387
</executions>

Diff for: src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java

+8-10
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
* @author Nicolas Cirigliano
5555
* @author Jens Schauder
5656
* @author Gabriel Basilio
57+
* @author Greg Turnquist
5758
*/
5859
public abstract class JpaQueryExecution {
5960

@@ -319,19 +320,16 @@ protected Object doExecute(AbstractJpaQuery jpaQuery, JpaParametersParameterAcce
319320
boolean returnsResultSet = storedProcedure.execute();
320321

321322
if (returnsResultSet) {
322-
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive())
323-
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
324-
325-
List<?> result = storedProcedure.getResultList();
326323

327-
if (!storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) {
328-
if (result.isEmpty())
329-
return null;
330-
if (result.size() == 1)
331-
return result.get(0);
324+
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) {
325+
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
332326
}
333327

334-
return result;
328+
if (storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) {
329+
return storedProcedure.getResultList();
330+
} else {
331+
return storedProcedure.getSingleResult();
332+
}
335333
}
336334

337335
return storedProcedureJpaQuery.extractOutputValue(storedProcedure);

Diff for: src/main/java/org/springframework/data/jpa/repository/query/Procedure.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
String outputParameterName() default "";
5555

5656
/**
57-
* Whether the procedure returns a Ref Cursor from the database {@code false}.
57+
* Whether the procedure returns a Ref Cursor from the database - defaults to {@code false}.
5858
*/
5959
boolean refCursor() default false;
6060
}

Diff for: src/main/java/org/springframework/data/jpa/repository/query/ProcedureParameter.java

+36-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2020 the original author or authors.
2+
* Copyright 2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,23 +16,27 @@
1616

1717
package org.springframework.data.jpa.repository.query;
1818

19-
import org.springframework.lang.Nullable;
19+
import java.util.Objects;
2020

2121
import javax.persistence.ParameterMode;
2222

23+
import org.springframework.lang.Nullable;
24+
2325
/**
24-
* This class represents a Stored Procedure Parameter
25-
* and an instance of the annotation {@link javax.persistence.StoredProcedureParameter}.
26+
* This class represents a Stored Procedure Parameter and an instance of the annotation
27+
* {@link javax.persistence.StoredProcedureParameter}.
2628
*
2729
* @author Gabriel Basilio
30+
* @author Greg Turnquist
2831
*/
29-
public class ProcedureParameter {
32+
class ProcedureParameter {
3033

3134
private final String name;
3235
private final ParameterMode mode;
3336
private final Class<?> type;
3437

35-
public ProcedureParameter(@Nullable String name, ParameterMode mode, Class<?> type) {
38+
ProcedureParameter(@Nullable String name, ParameterMode mode, Class<?> type) {
39+
3640
this.name = name;
3741
this.mode = mode;
3842
this.type = type;
@@ -49,4 +53,29 @@ public ParameterMode getMode() {
4953
public Class<?> getType() {
5054
return type;
5155
}
52-
}
56+
57+
@Override
58+
public boolean equals(Object o) {
59+
60+
if (this == o) {
61+
return true;
62+
}
63+
64+
if (!(o instanceof ProcedureParameter)) {
65+
return false;
66+
}
67+
68+
ProcedureParameter that = (ProcedureParameter) o;
69+
return Objects.equals(name, that.name) && mode == that.mode && Objects.equals(type, that.type);
70+
}
71+
72+
@Override
73+
public int hashCode() {
74+
return Objects.hash(name, mode, type);
75+
}
76+
77+
@Override
78+
public String toString() {
79+
return "ProcedureParameter{" + "name='" + name + '\'' + ", mode=" + mode + ", type=" + type + '}';
80+
}
81+
}

Diff for: src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributeSource.java

+42-20
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import java.lang.reflect.Method;
1919
import java.util.ArrayList;
2020
import java.util.Arrays;
21+
import java.util.Collections;
2122
import java.util.List;
23+
import java.util.stream.Collectors;
2224

2325
import javax.persistence.NamedStoredProcedureQueries;
2426
import javax.persistence.NamedStoredProcedureQuery;
@@ -28,6 +30,7 @@
2830
import org.springframework.core.annotation.AnnotatedElementUtils;
2931
import org.springframework.lang.Nullable;
3032
import org.springframework.util.Assert;
33+
import org.springframework.util.ObjectUtils;
3134
import org.springframework.util.StringUtils;
3235

3336
/**
@@ -40,6 +43,7 @@
4043
* @author Diego Diez
4144
* @author Jeff Sheets
4245
* @author Gabriel Basilio
46+
* @author Greg Turnquist
4347
* @since 1.6
4448
*/
4549
enum StoredProcedureAttributeSource {
@@ -69,9 +73,9 @@ public StoredProcedureAttributes createFrom(Method method, JpaEntityMetadata<?>
6973
}
7074

7175
String procedureName = deriveProcedureNameFrom(method, procedure);
72-
if (StringUtils.isEmpty(procedureName)) {
73-
throw new IllegalArgumentException("Could not determine name of procedure for @Procedure annotated method: "
74-
+ method);
76+
if (ObjectUtils.isEmpty(procedureName)) {
77+
throw new IllegalArgumentException(
78+
"Could not determine name of procedure for @Procedure annotated method: " + method);
7579
}
7680

7781
return new StoredProcedureAttributes(procedureName, createOutputProcedureParameterFrom(method, procedure));
@@ -96,42 +100,57 @@ private String deriveProcedureNameFrom(Method method, Procedure procedure) {
96100
}
97101

98102
/**
103+
* Extract procedure attributes from method and procedure.
104+
*
99105
* @param method
100106
* @param namedStoredProc
101107
* @param procedure
102108
* @return
103109
*/
104-
private StoredProcedureAttributes newProcedureAttributesFrom(Method method,
105-
NamedStoredProcedureQuery namedStoredProc, Procedure procedure) {
110+
private StoredProcedureAttributes newProcedureAttributesFrom(Method method, NamedStoredProcedureQuery namedStoredProc,
111+
Procedure procedure) {
106112

107-
List<ProcedureParameter> outputParameters = new ArrayList<>();
113+
List<ProcedureParameter> outputParameters;
108114

109115
if (!procedure.outputParameterName().isEmpty()) {
116+
110117
// we give the output parameter definition from the @Procedure annotation precedence
111-
outputParameters.add(createOutputProcedureParameterFrom(method, procedure));
118+
outputParameters = Collections.singletonList(createOutputProcedureParameterFrom(method, procedure));
112119
} else {
113120

114121
// try to discover the output parameter
115-
List<StoredProcedureParameter> namedProcedureOutputParameters = extractOutputParametersFrom(namedStoredProc);
116-
117-
for (StoredProcedureParameter outputParameter : namedProcedureOutputParameters) {
118-
outputParameters.add(new ProcedureParameter(
119-
outputParameter.name(), outputParameter.mode(), outputParameter.type()));
120-
}
122+
outputParameters = extractOutputParametersFrom(namedStoredProc).stream() //
123+
.map(namedParameter -> new ProcedureParameter(namedParameter.name(), namedParameter.mode(),
124+
namedParameter.type())) //
125+
.collect(Collectors.toList());
121126
}
122127

123128
return new StoredProcedureAttributes(namedStoredProc.name(), outputParameters, true);
124129
}
125130

131+
/**
132+
* Create a {@link ProcedureParameter} from relevant {@link Method} and {@link Procedure}.
133+
*
134+
* @param method
135+
* @param procedure
136+
* @return
137+
*/
126138
private ProcedureParameter createOutputProcedureParameterFrom(Method method, Procedure procedure) {
139+
127140
return new ProcedureParameter(procedure.outputParameterName(),
128-
procedure.refCursor() ? ParameterMode.REF_CURSOR : ParameterMode.OUT,
129-
method.getReturnType());
141+
procedure.refCursor() ? ParameterMode.REF_CURSOR : ParameterMode.OUT, method.getReturnType());
130142
}
131143

144+
/**
145+
* Translate all the {@Link NamedStoredProcedureQuery} parameters into a {@link List} of
146+
* {@link StoredProcedureParameter}s.
147+
*
148+
* @param namedStoredProc
149+
* @return
150+
*/
132151
private List<StoredProcedureParameter> extractOutputParametersFrom(NamedStoredProcedureQuery namedStoredProc) {
133152

134-
List<StoredProcedureParameter> outputParameters = new ArrayList<StoredProcedureParameter>();
153+
List<StoredProcedureParameter> outputParameters = new ArrayList<>();
135154

136155
for (StoredProcedureParameter param : namedStoredProc.parameters()) {
137156

@@ -190,9 +209,12 @@ private NamedStoredProcedureQuery tryFindAnnotatedNamedStoredProcedureQuery(Meth
190209
* @param procedure
191210
* @return
192211
*/
193-
private String derivedNamedProcedureNameFrom(Method method, JpaEntityMetadata<?> entityMetadata, Procedure procedure) {
194-
return StringUtils.hasText(procedure.name()) ? procedure.name() : entityMetadata.getEntityName() + "."
195-
+ method.getName();
212+
private String derivedNamedProcedureNameFrom(Method method, JpaEntityMetadata<?> entityMetadata,
213+
Procedure procedure) {
214+
215+
return StringUtils.hasText(procedure.name()) //
216+
? procedure.name() //
217+
: entityMetadata.getEntityName() + "." + method.getName();
196218
}
197219

198220
/**
@@ -201,7 +223,7 @@ private String derivedNamedProcedureNameFrom(Method method, JpaEntityMetadata<?>
201223
*/
202224
private List<NamedStoredProcedureQuery> collectNamedStoredProcedureQueriesFrom(Class<?> entityType) {
203225

204-
List<NamedStoredProcedureQuery> queries = new ArrayList<NamedStoredProcedureQuery>();
226+
List<NamedStoredProcedureQuery> queries = new ArrayList<>();
205227

206228
NamedStoredProcedureQueries namedQueriesAnnotation = AnnotatedElementUtils.findMergedAnnotation(entityType,
207229
NamedStoredProcedureQueries.class);

Diff for: src/main/java/org/springframework/data/jpa/repository/query/StoredProcedureAttributes.java

+18-14
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@
1515
*/
1616
package org.springframework.data.jpa.repository.query;
1717

18-
import org.springframework.lang.Nullable;
19-
import org.springframework.util.Assert;
20-
import org.springframework.util.StringUtils;
21-
22-
import javax.persistence.StoredProcedureQuery;
2318
import java.util.Collections;
2419
import java.util.List;
2520
import java.util.stream.Collectors;
2621
import java.util.stream.IntStream;
2722

23+
import javax.persistence.StoredProcedureQuery;
24+
25+
import org.springframework.util.Assert;
26+
import org.springframework.util.StringUtils;
27+
2828
/**
2929
* Stored procedure configuration for JPA 2.1 {@link StoredProcedureQuery}s.
3030
*
@@ -48,7 +48,7 @@ class StoredProcedureAttributes {
4848
/**
4949
* Creates a new {@link StoredProcedureAttributes}.
5050
*
51-
* @param procedureName must not be {@literal null}.
51+
* @param procedureName must not be {@literal null}.
5252
*/
5353
StoredProcedureAttributes(String procedureName, ProcedureParameter parameter) {
5454
this(procedureName, Collections.singletonList(parameter), false);
@@ -57,14 +57,16 @@ class StoredProcedureAttributes {
5757
/**
5858
* Creates a new {@link StoredProcedureAttributes}.
5959
*
60-
* @param procedureName must not be {@literal null}.
60+
* @param procedureName must not be {@literal null}.
6161
* @param namedStoredProcedure flag signaling if the stored procedure has a name.
6262
*/
63-
StoredProcedureAttributes(String procedureName, List<ProcedureParameter> outputProcedureParameters, boolean namedStoredProcedure) {
63+
StoredProcedureAttributes(String procedureName, List<ProcedureParameter> outputProcedureParameters,
64+
boolean namedStoredProcedure) {
6465

6566
Assert.notNull(procedureName, "ProcedureName must not be null!");
6667
Assert.notNull(outputProcedureParameters, "OutputProcedureParameters must not be null!");
67-
Assert.isTrue(outputProcedureParameters.size() != 1 || outputProcedureParameters.get(0) != null, "ProcedureParameters must not have size 1 with a null value");
68+
Assert.isTrue(outputProcedureParameters.size() != 1 || outputProcedureParameters.get(0) != null,
69+
"ProcedureParameters must not have size 1 with a null value");
6870

6971
this.procedureName = procedureName;
7072
this.namedStoredProcedure = namedStoredProcedure;
@@ -77,15 +79,16 @@ class StoredProcedureAttributes {
7779
}
7880

7981
private List<ProcedureParameter> getParametersWithCompletedNames(List<ProcedureParameter> procedureParameters) {
80-
return IntStream.range(0, procedureParameters.size())
81-
.mapToObj(i -> getParameterWithCompletedName(procedureParameters.get(i), i))
82+
83+
return IntStream.range(0, procedureParameters.size()) //
84+
.mapToObj(i -> getParameterWithCompletedName(procedureParameters.get(i), i)) //
8285
.collect(Collectors.toList());
8386
}
8487

8588
private ProcedureParameter getParameterWithCompletedName(ProcedureParameter parameter, int i) {
86-
return new ProcedureParameter(
87-
completeOutputParameterName(i, parameter.getName()),
88-
parameter.getMode(), parameter.getType());
89+
90+
return new ProcedureParameter(completeOutputParameterName(i, parameter.getName()), parameter.getMode(),
91+
parameter.getType());
8992
}
9093

9194
private String completeOutputParameterName(int i, String paramName) {
@@ -130,6 +133,7 @@ public List<ProcedureParameter> getOutputProcedureParameters() {
130133
* @return
131134
*/
132135
public boolean hasReturnValue() {
136+
133137
if (getOutputProcedureParameters().isEmpty())
134138
return false;
135139

0 commit comments

Comments
 (0)