@Override public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) { if (meta.getSqlType() == Types.OTHER && REF_CURSOR_NAME.equals(meta.getTypeName())) { return new SqlOutParameter(parameterName, getRefCursorSqlType(), new ColumnMapRowMapper()); } else { return super.createDefaultOutParameter(parameterName, meta); } }
/** * Reconcile the provided parameters with available metadata and add new ones where appropriate. */ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) { final List<SqlParameter> declaredReturnParams = new ArrayList<SqlParameter>(); final Map<String, SqlParameter> declaredParams = new LinkedHashMap<String, SqlParameter>(); boolean returnDeclared = false; List<String> outParamNames = new ArrayList<String>(); List<String> metaDataParamNames = new ArrayList<String>(); // Get the names of the meta data parameters for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) { metaDataParamNames.add(meta.getParameterName().toLowerCase()); } } // Separate implicit return parameters from explicit parameters... for (SqlParameter param : parameters) { if (param.isResultsParameter()) { declaredReturnParams.add(param); } else { String paramName = param.getName(); if (paramName == null) { throw new IllegalArgumentException( "Anonymous parameters not supported for calls - " + "please specify a name for the parameter of SQL type " + param.getSqlType()); } 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 (logger.isDebugEnabled()) { logger.debug( "Using declared out parameter '" + paramName + "' for function return value"); } setFunctionReturnName(paramName); returnDeclared = true; } } } } } setOutParameterNames(outParamNames); List<SqlParameter> workParams = new ArrayList<SqlParameter>(); workParams.addAll(declaredReturnParams); if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) { workParams.addAll(declaredParams.values()); return workParams; } Map<String, String> limitedInParamNamesMap = new HashMap<String, String>(this.limitedInParameterNames.size()); for (String limitedParamName : this.limitedInParameterNames) { limitedInParamNamesMap.put( this.metaDataProvider.parameterNameToUse(limitedParamName).toLowerCase(), limitedParamName); } for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { String paramNameToCheck = null; if (meta.getParameterName() != null) { paramNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase(); } String paramNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName()); if (declaredParams.containsKey(paramNameToCheck) || (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) { SqlParameter param; if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { param = declaredParams.get(getFunctionReturnName()); if (param == null && getOutParameterNames().size() > 0) { param = declaredParams.get(getOutParameterNames().get(0).toLowerCase()); } if (param == null) { throw new InvalidDataAccessApiUsageException( "Unable to locate declared parameter for function return value - " + " add a SqlOutParameter with name '" + getFunctionReturnName() + "'"); } else { setFunctionReturnName(param.getName()); } } else { param = declaredParams.get(paramNameToCheck); } if (param != null) { workParams.add(param); if (logger.isDebugEnabled()) { logger.debug( "Using declared parameter for '" + (paramNameToUse != null ? paramNameToUse : getFunctionReturnName()) + "'"); } } } else { if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { if (!isFunction() && !isReturnValueRequired() && this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) { if (logger.isDebugEnabled()) { logger.debug( "Bypassing metadata return parameter for '" + meta.getParameterName() + "'"); } } else { String returnNameToUse = (StringUtils.hasLength(meta.getParameterName()) ? paramNameToUse : getFunctionReturnName()); workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta)); if (isFunction()) { setFunctionReturnName(returnNameToUse); outParamNames.add(returnNameToUse); } if (logger.isDebugEnabled()) { logger.debug("Added metadata return parameter for '" + returnNameToUse + "'"); } } } else { if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) { workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta)); outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { logger.debug("Added metadata out parameter for '" + paramNameToUse + "'"); } } else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) { workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta)); outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'"); } } else { if (this.limitedInParameterNames.isEmpty() || limitedInParamNamesMap.containsKey(paramNameToUse.toLowerCase())) { workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta)); if (logger.isDebugEnabled()) { logger.debug("Added metadata in parameter for '" + paramNameToUse + "'"); } } else { if (logger.isDebugEnabled()) { logger.debug( "Limited set of parameters " + limitedInParamNamesMap.keySet() + " skipped parameter for '" + paramNameToUse + "'"); } } } } } } return workParams; }