Example usage for org.springframework.dao InvalidDataAccessApiUsageException InvalidDataAccessApiUsageException

List of usage examples for org.springframework.dao InvalidDataAccessApiUsageException InvalidDataAccessApiUsageException

Introduction

In this page you can find the example usage for org.springframework.dao InvalidDataAccessApiUsageException InvalidDataAccessApiUsageException.

Prototype

public InvalidDataAccessApiUsageException(String msg) 

Source Link

Document

Constructor for InvalidDataAccessApiUsageException.

Usage

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;
}