List of usage examples for org.springframework.dao InvalidDataAccessApiUsageException InvalidDataAccessApiUsageException
public InvalidDataAccessApiUsageException(String msg)
From source file:org.springframework.jdbc.core.metadata.CallMetaDataContext.java
/** * Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided * by the JDBC driver used for the database in use. * @param parameterName the name of the parameter (also used as the name of the List returned in the output) * @param rowMapper a RowMapper implementation used to map the data returned in the result set * @return the appropriate SqlParameter// w w w. ja v a2 s .c o m */ public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) { CallMetaDataProvider provider = obtainMetaDataProvider(); if (provider.isReturnResultSetSupported()) { return new SqlReturnResultSet(parameterName, rowMapper); } else { if (provider.isRefCursorSupported()) { return new SqlOutParameter(parameterName, provider.getRefCursorSqlType(), rowMapper); } else { throw new InvalidDataAccessApiUsageException( "Return of a ResultSet from a stored procedure is not supported."); } } }
From source file:org.springframework.jdbc.core.metadata.CallMetaDataContext.java
/** * Reconcile the provided parameters with available metadata and add new ones where appropriate. *///from w w w .ja v a2 s . c om protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) { CallMetaDataProvider provider = obtainMetaDataProvider(); final List<SqlParameter> declaredReturnParams = new ArrayList<>(); final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>(); boolean returnDeclared = false; List<String> outParamNames = new ArrayList<>(); List<String> metaDataParamNames = new ArrayList<>(); // Get the names of the meta data parameters for (CallParameterMetaData meta : provider.getCallParameterMetaData()) { if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) { metaDataParamNames.add(lowerCase(meta.getParameterName())); } } // 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 = lowerCase(provider.parameterNameToUse(paramName)); 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<>(); workParams.addAll(declaredReturnParams); if (!provider.isProcedureColumnMetaDataUsed()) { workParams.addAll(declaredParams.values()); return workParams; } Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size()); for (String limitedParamName : this.limitedInParameterNames) { limitedInParamNamesMap.put(lowerCase(provider.parameterNameToUse(limitedParamName)), limitedParamName); } for (CallParameterMetaData meta : provider.getCallParameterMetaData()) { String paramName = meta.getParameterName(); String paramNameToCheck = null; if (paramName != null) { paramNameToCheck = lowerCase(provider.parameterNameToUse(paramName)); } String paramNameToUse = provider.parameterNameToUse(paramName); if (declaredParams.containsKey(paramNameToCheck) || (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) { SqlParameter param; if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { param = declaredParams.get(getFunctionReturnName()); if (param == null && !getOutParameterNames().isEmpty()) { 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 if (paramName != null) { setFunctionReturnName(paramName); } } 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() && paramName != null && provider.byPassReturnParameter(paramName)) { if (logger.isDebugEnabled()) { logger.debug("Bypassing metadata return parameter for '" + paramName + "'"); } } else { String returnNameToUse = (StringUtils.hasLength(paramNameToUse) ? paramNameToUse : getFunctionReturnName()); workParams.add(provider.createDefaultOutParameter(returnNameToUse, meta)); if (isFunction()) { setFunctionReturnName(returnNameToUse); outParamNames.add(returnNameToUse); } if (logger.isDebugEnabled()) { logger.debug("Added metadata return parameter for '" + returnNameToUse + "'"); } } } else { if (paramNameToUse == null) { paramNameToUse = ""; } if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) { workParams.add(provider.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(provider.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(lowerCase(paramNameToUse))) { workParams.add(provider.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; }
From source file:org.springframework.jdbc.core.metadata.GenericCallMetaDataProvider.java
/** * Process the procedure column metadata *//*from ww w . j a va 2 s . c o m*/ private void processProcedureColumns(DatabaseMetaData databaseMetaData, @Nullable String catalogName, @Nullable String schemaName, @Nullable String procedureName) { String metaDataCatalogName = metaDataCatalogNameToUse(catalogName); String metaDataSchemaName = metaDataSchemaNameToUse(schemaName); String metaDataProcedureName = procedureNameToUse(procedureName); if (logger.isDebugEnabled()) { logger.debug("Retrieving metadata for " + metaDataCatalogName + '/' + metaDataSchemaName + '/' + metaDataProcedureName); } ResultSet procs = null; try { procs = databaseMetaData.getProcedures(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName); List<String> found = new ArrayList<>(); while (procs.next()) { found.add(procs.getString("PROCEDURE_CAT") + '.' + procs.getString("PROCEDURE_SCHEM") + '.' + procs.getString("PROCEDURE_NAME")); } procs.close(); if (found.size() > 1) { throw new InvalidDataAccessApiUsageException( "Unable to determine the correct call signature - multiple " + "procedures/functions/signatures for '" + metaDataProcedureName + "': found " + found); } else if (found.isEmpty()) { if (metaDataProcedureName != null && metaDataProcedureName.contains(".") && !StringUtils.hasText(metaDataCatalogName)) { String packageName = metaDataProcedureName.substring(0, metaDataProcedureName.indexOf(".")); throw new InvalidDataAccessApiUsageException( "Unable to determine the correct call signature for '" + metaDataProcedureName + "' - package name should be specified separately using '.withCatalogName(\"" + packageName + "\")'"); } else if ("Oracle".equals(databaseMetaData.getDatabaseProductName())) { if (logger.isDebugEnabled()) { logger.debug("Oracle JDBC driver did not return procedure/function/signature for '" + metaDataProcedureName + "' - assuming a non-exposed synonym"); } } else { throw new InvalidDataAccessApiUsageException( "Unable to determine the correct call signature - no " + "procedure/function/signature for '" + metaDataProcedureName + "'"); } } procs = databaseMetaData.getProcedureColumns(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null); while (procs.next()) { String columnName = procs.getString("COLUMN_NAME"); int columnType = procs.getInt("COLUMN_TYPE"); if (columnName == null && (columnType == DatabaseMetaData.procedureColumnIn || columnType == DatabaseMetaData.procedureColumnInOut || columnType == DatabaseMetaData.procedureColumnOut)) { if (logger.isDebugEnabled()) { logger.debug("Skipping metadata for: " + columnType + " " + procs.getInt("DATA_TYPE") + " " + procs.getString("TYPE_NAME") + " " + procs.getInt("NULLABLE") + " (probably a member of a collection)"); } } else { CallParameterMetaData meta = new CallParameterMetaData(columnName, columnType, procs.getInt("DATA_TYPE"), procs.getString("TYPE_NAME"), procs.getInt("NULLABLE") == DatabaseMetaData.procedureNullable); this.callParameterMetaData.add(meta); if (logger.isDebugEnabled()) { logger.debug("Retrieved metadata: " + meta.getParameterName() + " " + meta.getParameterType() + " " + meta.getSqlType() + " " + meta.getTypeName() + " " + meta.isNullable()); } } } } catch (SQLException ex) { if (logger.isWarnEnabled()) { logger.warn("Error while retrieving metadata for procedure columns: " + ex); } } finally { try { if (procs != null) { procs.close(); } } catch (SQLException ex) { if (logger.isWarnEnabled()) { logger.warn("Problem closing ResultSet for procedure column metadata: " + ex); } } } }
From source file:org.springframework.jdbc.core.metadata.TableMetaDataContext.java
/** * Build the insert string based on configuration and metadata information * @return the insert string to be used/* w ww . j a va2 s . com*/ */ public String createInsertString(String... generatedKeyNames) { Set<String> keys = new LinkedHashSet<>(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } StringBuilder insertStatement = new StringBuilder(); insertStatement.append("INSERT INTO "); if (getSchemaName() != null) { insertStatement.append(getSchemaName()); insertStatement.append("."); } insertStatement.append(getTableName()); insertStatement.append(" ("); int columnCount = 0; for (String columnName : getTableColumns()) { if (!keys.contains(columnName.toUpperCase())) { columnCount++; if (columnCount > 1) { insertStatement.append(", "); } insertStatement.append(columnName); } } insertStatement.append(") VALUES("); if (columnCount < 1) { if (this.generatedKeyColumnsUsed) { logger.info("Unable to locate non-key columns for table '" + getTableName() + "' so an empty insert statement is generated"); } else { throw new InvalidDataAccessApiUsageException("Unable to locate columns for table '" + getTableName() + "' so an insert statement can't be generated"); } } for (int i = 0; i < columnCount; i++) { if (i > 0) { insertStatement.append(", "); } insertStatement.append("?"); } insertStatement.append(")"); return insertStatement.toString(); }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcCall.java
/** * Add a declared parameter to the list of parameters for the call. * <p>Only parameters declared as {@code SqlParameter} and {@code SqlInOutParameter} will * be used to provide input values. This is different from the {@code StoredProcedure} * class which - for backwards compatibility reasons - allows input values to be provided * for parameters declared as {@code SqlOutParameter}. * @param parameter the {@link SqlParameter} to add *//*from www . j ava 2s. com*/ public void addDeclaredParameter(SqlParameter parameter) { Assert.notNull(parameter, "The supplied parameter must not be null"); if (!StringUtils.hasText(parameter.getName())) { throw new InvalidDataAccessApiUsageException( "You must specify a parameter name when declaring parameters for \"" + getProcedureName() + "\""); } this.declaredParameters.add(parameter); if (logger.isDebugEnabled()) { logger.debug("Added declared parameter for [" + getProcedureName() + "]: " + parameter.getName()); } }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcCall.java
/** * Compile this JdbcCall using provided parameters and meta data plus other settings. * <p>This finalizes the configuration for this object and subsequent attempts to compile are * ignored. This will be implicitly called the first time an un-compiled call is executed. * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't * been correctly initialized, for example if no DataSource has been provided *///from w ww . j ava 2 s .co m public synchronized final void compile() throws InvalidDataAccessApiUsageException { if (!isCompiled()) { if (getProcedureName() == null) { throw new InvalidDataAccessApiUsageException("Procedure or Function name is required"); } try { this.jdbcTemplate.afterPropertiesSet(); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException(ex.getMessage()); } compileInternal(); this.compiled = true; if (logger.isDebugEnabled()) { logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") + " [" + getProcedureName() + "] compiled"); } } }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcInsert.java
/** * Compile this JdbcInsert using provided parameters and meta data plus other settings. * This finalizes the configuration for this object and subsequent attempts to compile are * ignored. This will be implicitly called the first time an un-compiled insert is executed. * @throws InvalidDataAccessApiUsageException if the object hasn't been correctly initialized, * for example if no DataSource has been provided *//*from w ww . j av a 2s .com*/ public synchronized final void compile() throws InvalidDataAccessApiUsageException { if (!isCompiled()) { if (getTableName() == null) { throw new InvalidDataAccessApiUsageException("Table name is required"); } try { this.jdbcTemplate.afterPropertiesSet(); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException(ex.getMessage()); } compileInternal(); this.compiled = true; if (logger.isDebugEnabled()) { logger.debug("JdbcInsert for table [" + getTableName() + "] compiled"); } } }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcInsert.java
/** * Method to check whether we are allowed to make any configuration changes at this time. * If the class has been compiled, then no further changes to the configuration are allowed. */// w w w .j ava 2 s .co m protected void checkIfConfigurationModificationIsAllowed() { if (isCompiled()) { throw new InvalidDataAccessApiUsageException( "Configuration can't be altered once the class has been compiled or used"); } }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcInsert.java
/** * Delegate method to execute the insert, generating any number of keys. *//*from ww w .j a v a 2 s.co m*/ private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<?> values) { if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values); } final KeyHolder keyHolder = new GeneratedKeyHolder(); if (this.tableMetaDataContext.isGetGeneratedKeysSupported()) { getJdbcTemplate().update(con -> { PreparedStatement ps = prepareStatementForGeneratedKeys(con); setParameterValues(ps, values, getInsertTypes()); return ps; }, keyHolder); } else { if (!this.tableMetaDataContext.isGetGeneratedKeysSimulated()) { throw new InvalidDataAccessResourceUsageException( "The getGeneratedKeys feature is not supported by this database"); } if (getGeneratedKeyNames().length < 1) { throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specified. " + "Using the generated keys features requires specifying the name(s) of the generated column(s)"); } if (getGeneratedKeyNames().length > 1) { throw new InvalidDataAccessApiUsageException( "Current database only supports retrieving the key for a single column. There are " + getGeneratedKeyNames().length + " columns specified: " + Arrays.asList(getGeneratedKeyNames())); } Assert.state(getTableName() != null, "No table name set"); final String keyQuery = this.tableMetaDataContext.getSimulationQueryForGetGeneratedKey(getTableName(), getGeneratedKeyNames()[0]); Assert.state(keyQuery != null, "Query for simulating get generated keys can't be null"); // This is a hack to be able to get the generated key from a database that doesn't support // get generated keys feature. HSQL is one, PostgreSQL is another. Postgres uses a RETURNING // clause while HSQL uses a second query that has to be executed with the same connection. if (keyQuery.toUpperCase().startsWith("RETURNING")) { Long key = getJdbcTemplate().queryForObject(getInsertString() + " " + keyQuery, values.toArray(new Object[values.size()]), Long.class); Map<String, Object> keys = new HashMap<>(1); keys.put(getGeneratedKeyNames()[0], key); keyHolder.getKeyList().add(keys); } else { getJdbcTemplate().execute((ConnectionCallback<Object>) con -> { // Do the insert PreparedStatement ps = null; try { ps = con.prepareStatement(getInsertString()); setParameterValues(ps, values, getInsertTypes()); ps.executeUpdate(); } finally { JdbcUtils.closeStatement(ps); } //Get the key Statement keyStmt = null; ResultSet rs = null; Map<String, Object> keys = new HashMap<>(1); try { keyStmt = con.createStatement(); rs = keyStmt.executeQuery(keyQuery); if (rs.next()) { long key = rs.getLong(1); keys.put(getGeneratedKeyNames()[0], key); keyHolder.getKeyList().add(keys); } } finally { JdbcUtils.closeResultSet(rs); JdbcUtils.closeStatement(keyStmt); } return null; }); } } return keyHolder; }
From source file:org.springframework.jdbc.core.simple.AbstractJdbcInsert.java
/** * Create a PreparedStatement to be used for an insert operation with generated keys. * @param con the Connection to use/*from w w w . j a v a 2s . c o m*/ * @return the PreparedStatement */ private PreparedStatement prepareStatementForGeneratedKeys(Connection con) throws SQLException { if (getGeneratedKeyNames().length < 1) { throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specified. " + "Using the generated keys features requires specifying the name(s) of the generated column(s)."); } PreparedStatement ps; if (this.tableMetaDataContext.isGeneratedKeysColumnNameArraySupported()) { if (logger.isDebugEnabled()) { logger.debug("Using generated keys support with array of column names."); } ps = con.prepareStatement(getInsertString(), getGeneratedKeyNames()); } else { if (logger.isDebugEnabled()) { logger.debug("Using generated keys support with Statement.RETURN_GENERATED_KEYS."); } ps = con.prepareStatement(getInsertString(), Statement.RETURN_GENERATED_KEYS); } return ps; }