Avoid NPE for anonymous SqlParameter in CallMetaDataContext
Issue: SPR-13628
(cherry picked from commit 6685c78)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -280,88 +280,94 @@ public class CallMetaDataContext {
|
|||||||
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
|
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
|
||||||
*/
|
*/
|
||||||
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
|
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
|
||||||
final List<SqlParameter> declaredReturnParameters = new ArrayList<SqlParameter>();
|
final List<SqlParameter> declaredReturnParams = new ArrayList<SqlParameter>();
|
||||||
final Map<String, SqlParameter> declaredParameters = new LinkedHashMap<String, SqlParameter>();
|
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<String, SqlParameter>();
|
||||||
boolean returnDeclared = false;
|
boolean returnDeclared = false;
|
||||||
List<String> outParameterNames = new ArrayList<String>();
|
List<String> outParamNames = new ArrayList<String>();
|
||||||
List<String> metaDataParameterNames = new ArrayList<String>();
|
List<String> metaDataParamNames = new ArrayList<String>();
|
||||||
|
|
||||||
// Get the names of the meta data parameters
|
// Get the names of the meta data parameters
|
||||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
||||||
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
|
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
|
||||||
metaDataParameterNames.add(meta.getParameterName().toLowerCase());
|
metaDataParamNames.add(meta.getParameterName().toLowerCase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separate implicit return parameters from explicit parameters...
|
// Separate implicit return parameters from explicit parameters...
|
||||||
for (SqlParameter parameter : parameters) {
|
for (SqlParameter param : parameters) {
|
||||||
if (parameter.isResultsParameter()) {
|
if (param.isResultsParameter()) {
|
||||||
declaredReturnParameters.add(parameter);
|
declaredReturnParams.add(param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameter.getName()).toLowerCase();
|
String paramName = param.getName();
|
||||||
declaredParameters.put(parameterNameToMatch, parameter);
|
if (paramName == null) {
|
||||||
if (parameter instanceof SqlOutParameter) {
|
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
|
||||||
outParameterNames.add(parameter.getName());
|
"please specify a name for the parameter of SQL type " + param.getSqlType());
|
||||||
if (isFunction() && !metaDataParameterNames.contains(parameterNameToMatch)) {
|
}
|
||||||
|
String paramNameToMatch = this.metaDataProvider.parameterNameToUse(paramName).toLowerCase();
|
||||||
|
declaredParams.put(paramNameToMatch, param);
|
||||||
|
if (param instanceof SqlOutParameter) {
|
||||||
|
outParamNames.add(paramName);
|
||||||
|
if (isFunction() && !metaDataParamNames.contains(paramNameToMatch)) {
|
||||||
if (!returnDeclared) {
|
if (!returnDeclared) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Using declared out parameter '" + parameter.getName() + "' for function return value");
|
logger.debug("Using declared out parameter '" + paramName +
|
||||||
|
"' for function return value");
|
||||||
}
|
}
|
||||||
setFunctionReturnName(parameter.getName());
|
setFunctionReturnName(paramName);
|
||||||
returnDeclared = true;
|
returnDeclared = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOutParameterNames(outParameterNames);
|
setOutParameterNames(outParamNames);
|
||||||
|
|
||||||
List<SqlParameter> workParameters = new ArrayList<SqlParameter>();
|
List<SqlParameter> workParams = new ArrayList<SqlParameter>();
|
||||||
workParameters.addAll(declaredReturnParameters);
|
workParams.addAll(declaredReturnParams);
|
||||||
|
|
||||||
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
||||||
workParameters.addAll(declaredParameters.values());
|
workParams.addAll(declaredParams.values());
|
||||||
return workParameters;
|
return workParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> limitedInParamNamesMap = new HashMap<String, String>(this.limitedInParameterNames.size());
|
Map<String, String> limitedInParamNamesMap = new HashMap<String, String>(this.limitedInParameterNames.size());
|
||||||
for (String limitedParameterName : this.limitedInParameterNames) {
|
for (String limitedParamName : this.limitedInParameterNames) {
|
||||||
limitedInParamNamesMap.put(
|
limitedInParamNamesMap.put(
|
||||||
this.metaDataProvider.parameterNameToUse(limitedParameterName).toLowerCase(), limitedParameterName);
|
this.metaDataProvider.parameterNameToUse(limitedParamName).toLowerCase(), limitedParamName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
||||||
String parNameToCheck = null;
|
String paramNameToCheck = null;
|
||||||
if (meta.getParameterName() != null) {
|
if (meta.getParameterName() != null) {
|
||||||
parNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase();
|
paramNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase();
|
||||||
}
|
}
|
||||||
String parNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName());
|
String paramNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName());
|
||||||
if (declaredParameters.containsKey(parNameToCheck) ||
|
if (declaredParams.containsKey(paramNameToCheck) ||
|
||||||
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
|
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
|
||||||
SqlParameter parameter;
|
SqlParameter param;
|
||||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
|
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
|
||||||
parameter = declaredParameters.get(getFunctionReturnName());
|
param = declaredParams.get(getFunctionReturnName());
|
||||||
if (parameter == null && getOutParameterNames().size() > 0) {
|
if (param == null && getOutParameterNames().size() > 0) {
|
||||||
parameter = declaredParameters.get(getOutParameterNames().get(0).toLowerCase());
|
param = declaredParams.get(getOutParameterNames().get(0).toLowerCase());
|
||||||
}
|
}
|
||||||
if (parameter == null) {
|
if (param == null) {
|
||||||
throw new InvalidDataAccessApiUsageException(
|
throw new InvalidDataAccessApiUsageException(
|
||||||
"Unable to locate declared parameter for function return value - " +
|
"Unable to locate declared parameter for function return value - " +
|
||||||
" add a SqlOutParameter with name \"" + getFunctionReturnName() +"\"");
|
" add a SqlOutParameter with name '" + getFunctionReturnName() + "'");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setFunctionReturnName(parameter.getName());
|
setFunctionReturnName(param.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parameter = declaredParameters.get(parNameToCheck);
|
param = declaredParams.get(paramNameToCheck);
|
||||||
}
|
}
|
||||||
if (parameter != null) {
|
if (param != null) {
|
||||||
workParameters.add(parameter);
|
workParams.add(param);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Using declared parameter for: " +
|
logger.debug("Using declared parameter for '" +
|
||||||
(parNameToUse == null ? getFunctionReturnName() : parNameToUse));
|
(paramNameToUse != null ? paramNameToUse : getFunctionReturnName()) + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,49 +376,49 @@ public class CallMetaDataContext {
|
|||||||
if (!isFunction() && !isReturnValueRequired() &&
|
if (!isFunction() && !isReturnValueRequired() &&
|
||||||
this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) {
|
this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Bypassing metadata return parameter for: " + meta.getParameterName());
|
logger.debug("Bypassing metadata return parameter for '" + meta.getParameterName() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String returnNameToUse =(StringUtils.hasLength(meta.getParameterName()) ?
|
String returnNameToUse =(StringUtils.hasLength(meta.getParameterName()) ?
|
||||||
parNameToUse : getFunctionReturnName());
|
paramNameToUse : getFunctionReturnName());
|
||||||
workParameters.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
|
workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
|
||||||
if (isFunction()) {
|
if (isFunction()) {
|
||||||
setFunctionReturnName(returnNameToUse);
|
setFunctionReturnName(returnNameToUse);
|
||||||
outParameterNames.add(returnNameToUse);
|
outParamNames.add(returnNameToUse);
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata return parameter for: " + returnNameToUse);
|
logger.debug("Added metadata return parameter for '" + returnNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
|
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
|
||||||
workParameters.add(this.metaDataProvider.createDefaultOutParameter(parNameToUse, meta));
|
workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta));
|
||||||
outParameterNames.add(parNameToUse);
|
outParamNames.add(paramNameToUse);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata out parameter for: " + parNameToUse);
|
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
|
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
|
||||||
workParameters.add(this.metaDataProvider.createDefaultInOutParameter(parNameToUse, meta));
|
workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta));
|
||||||
outParameterNames.add(parNameToUse);
|
outParamNames.add(paramNameToUse);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata in out parameter for: " + parNameToUse);
|
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.limitedInParameterNames.isEmpty() ||
|
if (this.limitedInParameterNames.isEmpty() ||
|
||||||
limitedInParamNamesMap.containsKey(parNameToUse.toLowerCase())) {
|
limitedInParamNamesMap.containsKey(paramNameToUse.toLowerCase())) {
|
||||||
workParameters.add(this.metaDataProvider.createDefaultInParameter(parNameToUse, meta));
|
workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta));
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata in parameter for: " + parNameToUse);
|
logger.debug("Added metadata in parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() +
|
logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() +
|
||||||
" skipped parameter for: " + parNameToUse);
|
" skipped parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,7 +426,7 @@ public class CallMetaDataContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return workParameters;
|
return workParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user