Skip to content

Commit

Permalink
Polishing.
Browse files Browse the repository at this point in the history
See: #1959, #409.
  • Loading branch information
gregturn committed Jul 9, 2021
1 parent 554bd3d commit 0a81bc6
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 109 deletions.
18 changes: 14 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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">
<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">

<modelVersion>4.0.0</modelVersion>

Expand Down Expand Up @@ -101,7 +102,9 @@
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.artifactId}-${project.version}.zip</file>
<file>
${project.build.directory}/${project.artifactId}-${project.version}.zip
</file>
<type>zip</type>
</artifact>
</artifacts>
Expand Down Expand Up @@ -358,7 +361,10 @@
<exclude>**/OpenJpa*</exclude>
<exclude>**/EclipseLink*</exclude>
</excludes>
<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>
<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>
</configuration>
</execution>
<execution>
Expand All @@ -371,7 +377,11 @@
<includes>
<include>**/EclipseLink*Tests.java</include>
</includes>
<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>
<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>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
* @author Nicolas Cirigliano
* @author Jens Schauder
* @author Gabriel Basilio
* @author Greg Turnquist
*/
public abstract class JpaQueryExecution {

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

if (returnsResultSet) {
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);
if (!SurroundingTransactionDetectorMethodInterceptor.INSTANCE.isSurroundingTransactionActive()) {
throw new InvalidDataAccessApiUsageException(NO_SURROUNDING_TRANSACTION);
}

return result;
if (storedProcedureJpaQuery.getQueryMethod().isCollectionQuery()) {
return storedProcedure.getResultList();
} else {
return storedProcedure.getSingleResult();
}
}

return storedProcedureJpaQuery.extractOutputValue(storedProcedure);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
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;
}
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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;
Expand All @@ -49,4 +53,29 @@ public ParameterMode getMode() {
public Class<?> getType() {
return type;
}
}

@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 + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
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;
Expand All @@ -28,6 +30,7 @@
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;

/**
Expand All @@ -40,6 +43,7 @@
* @author Diego Diez
* @author Jeff Sheets
* @author Gabriel Basilio
* @author Greg Turnquist
* @since 1.6
*/
enum StoredProcedureAttributeSource {
Expand Down Expand Up @@ -69,9 +73,9 @@ public StoredProcedureAttributes createFrom(Method method, JpaEntityMetadata<?>
}

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));
Expand All @@ -96,42 +100,57 @@ private String deriveProcedureNameFrom(Method method, Procedure procedure) {
}

/**
* 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<ProcedureParameter> outputParameters = new ArrayList<>();
List<ProcedureParameter> 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<StoredProcedureParameter> 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<StoredProcedureParameter> extractOutputParametersFrom(NamedStoredProcedureQuery namedStoredProc) {

List<StoredProcedureParameter> outputParameters = new ArrayList<StoredProcedureParameter>();
List<StoredProcedureParameter> outputParameters = new ArrayList<>();

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

Expand Down Expand Up @@ -190,9 +209,12 @@ private NamedStoredProcedureQuery tryFindAnnotatedNamedStoredProcedureQuery(Meth
* @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();
}

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

List<NamedStoredProcedureQuery> queries = new ArrayList<NamedStoredProcedureQuery>();
List<NamedStoredProcedureQuery> queries = new ArrayList<>();

NamedStoredProcedureQueries namedQueriesAnnotation = AnnotatedElementUtils.findMergedAnnotation(entityType,
NamedStoredProcedureQueries.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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);
Expand All @@ -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<ProcedureParameter> outputProcedureParameters, boolean namedStoredProcedure) {
StoredProcedureAttributes(String procedureName, List<ProcedureParameter> 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;
Expand All @@ -77,15 +79,16 @@ class StoredProcedureAttributes {
}

private List<ProcedureParameter> getParametersWithCompletedNames(List<ProcedureParameter> 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) {
Expand Down Expand Up @@ -130,6 +133,7 @@ public List<ProcedureParameter> getOutputProcedureParameters() {
* @return
*/
public boolean hasReturnValue() {

if (getOutputProcedureParameters().isEmpty())
return false;

Expand Down
Loading

0 comments on commit 0a81bc6

Please sign in to comment.