Search in sources :

Example 31 with InvalidDataAccessApiUsageException

use of org.springframework.dao.InvalidDataAccessApiUsageException in project spring-framework by spring-projects.

the class GenericCallMetaDataProvider method processProcedureColumns.

/**
 * Process the procedure column meta-data.
 */
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 meta-data for " + metaDataCatalogName + '/' + metaDataSchemaName + '/' + metaDataProcedureName);
    }
    try {
        List<String> found = new ArrayList<>();
        boolean function = false;
        try (ResultSet procedures = databaseMetaData.getProcedures(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName)) {
            while (procedures.next()) {
                found.add(procedures.getString("PROCEDURE_CAT") + '.' + procedures.getString("PROCEDURE_SCHEM") + '.' + procedures.getString("PROCEDURE_NAME"));
            }
        }
        if (found.isEmpty()) {
            // Functions not exposed as procedures anymore on PostgreSQL driver 42.2.11
            try (ResultSet functions = databaseMetaData.getFunctions(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName)) {
                while (functions.next()) {
                    found.add(functions.getString("FUNCTION_CAT") + '.' + functions.getString("FUNCTION_SCHEM") + '.' + functions.getString("FUNCTION_NAME"));
                    function = true;
                }
            }
        }
        if (found.size() > 1) {
            throw new InvalidDataAccessApiUsageException("Unable to determine the correct call signature - multiple signatures for '" + metaDataProcedureName + "': found " + found + " " + (function ? "functions" : "procedures"));
        } 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 + "'");
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Retrieving column meta-data for " + (function ? "function" : "procedure") + ' ' + metaDataCatalogName + '/' + metaDataSchemaName + '/' + metaDataProcedureName);
        }
        try (ResultSet columns = function ? databaseMetaData.getFunctionColumns(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null) : databaseMetaData.getProcedureColumns(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null)) {
            while (columns.next()) {
                String columnName = columns.getString("COLUMN_NAME");
                int columnType = columns.getInt("COLUMN_TYPE");
                if (columnName == null && isInOrOutColumn(columnType, function)) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Skipping meta-data for: " + columnType + " " + columns.getInt("DATA_TYPE") + " " + columns.getString("TYPE_NAME") + " " + columns.getInt("NULLABLE") + " (probably a member of a collection)");
                    }
                } else {
                    int nullable = (function ? DatabaseMetaData.functionNullable : DatabaseMetaData.procedureNullable);
                    CallParameterMetaData meta = new CallParameterMetaData(function, columnName, columnType, columns.getInt("DATA_TYPE"), columns.getString("TYPE_NAME"), columns.getInt("NULLABLE") == nullable);
                    this.callParameterMetaData.add(meta);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Retrieved meta-data: " + meta.getParameterName() + " " + meta.getParameterType() + " " + meta.getSqlType() + " " + meta.getTypeName() + " " + meta.isNullable());
                    }
                }
            }
        }
    } catch (SQLException ex) {
        if (logger.isWarnEnabled()) {
            logger.warn("Error while retrieving meta-data for procedure columns. " + "Consider declaring explicit parameters -- for example, via SimpleJdbcCall#addDeclaredParameter().", ex);
        }
    // Although we could invoke `this.callParameterMetaData.clear()` so that
    // we don't retain a partial list of column names (like we do in
    // GenericTableMetaDataProvider.processTableColumns(...)), we choose
    // not to do that here, since invocation of the stored procedure will
    // likely fail anyway with an incorrect argument list.
    }
}
Also used : SQLException(java.sql.SQLException) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet)

Example 32 with InvalidDataAccessApiUsageException

use of org.springframework.dao.InvalidDataAccessApiUsageException in project spring-framework by spring-projects.

the class AbstractJdbcCall method compile.

// -------------------------------------------------------------------------
// Methods handling compilation issues
// -------------------------------------------------------------------------
/**
 * 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
 */
public final synchronized 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");
        }
    }
}
Also used : InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException)

Example 33 with InvalidDataAccessApiUsageException

use of org.springframework.dao.InvalidDataAccessApiUsageException in project spring-framework by spring-projects.

the class SQLExceptionSubclassTranslatorTests method errorCodeTranslation.

@Test
public void errorCodeTranslation() {
    SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES);
    SQLException dataIntegrityViolationEx = SQLExceptionSubclassFactory.newSQLDataException("", "", 0);
    DataIntegrityViolationException divex = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx);
    assertThat(divex.getCause()).isEqualTo(dataIntegrityViolationEx);
    SQLException featureNotSupEx = SQLExceptionSubclassFactory.newSQLFeatureNotSupportedException("", "", 0);
    InvalidDataAccessApiUsageException idaex = (InvalidDataAccessApiUsageException) sext.translate("task", "SQL", featureNotSupEx);
    assertThat(idaex.getCause()).isEqualTo(featureNotSupEx);
    SQLException dataIntegrityViolationEx2 = SQLExceptionSubclassFactory.newSQLIntegrityConstraintViolationException("", "", 0);
    DataIntegrityViolationException divex2 = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx2);
    assertThat(divex2.getCause()).isEqualTo(dataIntegrityViolationEx2);
    SQLException permissionDeniedEx = SQLExceptionSubclassFactory.newSQLInvalidAuthorizationSpecException("", "", 0);
    PermissionDeniedDataAccessException pdaex = (PermissionDeniedDataAccessException) sext.translate("task", "SQL", permissionDeniedEx);
    assertThat(pdaex.getCause()).isEqualTo(permissionDeniedEx);
    SQLException dataAccessResourceEx = SQLExceptionSubclassFactory.newSQLNonTransientConnectionException("", "", 0);
    DataAccessResourceFailureException darex = (DataAccessResourceFailureException) sext.translate("task", "SQL", dataAccessResourceEx);
    assertThat(darex.getCause()).isEqualTo(dataAccessResourceEx);
    SQLException badSqlEx2 = SQLExceptionSubclassFactory.newSQLSyntaxErrorException("", "", 0);
    BadSqlGrammarException bsgex2 = (BadSqlGrammarException) sext.translate("task", "SQL2", badSqlEx2);
    assertThat(bsgex2.getSql()).isEqualTo("SQL2");
    assertThat((Object) bsgex2.getSQLException()).isEqualTo(badSqlEx2);
    SQLException tranRollbackEx = SQLExceptionSubclassFactory.newSQLTransactionRollbackException("", "", 0);
    ConcurrencyFailureException cfex = (ConcurrencyFailureException) sext.translate("task", "SQL", tranRollbackEx);
    assertThat(cfex.getCause()).isEqualTo(tranRollbackEx);
    SQLException transientConnEx = SQLExceptionSubclassFactory.newSQLTransientConnectionException("", "", 0);
    TransientDataAccessResourceException tdarex = (TransientDataAccessResourceException) sext.translate("task", "SQL", transientConnEx);
    assertThat(tdarex.getCause()).isEqualTo(transientConnEx);
    SQLException transientConnEx2 = SQLExceptionSubclassFactory.newSQLTimeoutException("", "", 0);
    QueryTimeoutException tdarex2 = (QueryTimeoutException) sext.translate("task", "SQL", transientConnEx2);
    assertThat(tdarex2.getCause()).isEqualTo(transientConnEx2);
    SQLException recoverableEx = SQLExceptionSubclassFactory.newSQLRecoverableException("", "", 0);
    RecoverableDataAccessException rdaex2 = (RecoverableDataAccessException) sext.translate("task", "SQL", recoverableEx);
    assertThat(rdaex2.getCause()).isEqualTo(recoverableEx);
    // Test classic error code translation. We should move there next if the exception we pass in is not one
    // of the new sub-classes.
    SQLException sexEct = new SQLException("", "", 1);
    BadSqlGrammarException bsgEct = (BadSqlGrammarException) sext.translate("task", "SQL-ECT", sexEct);
    assertThat(bsgEct.getSql()).isEqualTo("SQL-ECT");
    assertThat((Object) bsgEct.getSQLException()).isEqualTo(sexEct);
    // Test fallback. We assume that no database will ever return this error code,
    // but 07xxx will be bad grammar picked up by the fallback SQLState translator
    SQLException sexFbt = new SQLException("", "07xxx", 666666666);
    BadSqlGrammarException bsgFbt = (BadSqlGrammarException) sext.translate("task", "SQL-FBT", sexFbt);
    assertThat(bsgFbt.getSql()).isEqualTo("SQL-FBT");
    assertThat((Object) bsgFbt.getSQLException()).isEqualTo(sexFbt);
    // and 08xxx will be data resource failure (non-transient) picked up by the fallback SQLState translator
    SQLException sexFbt2 = new SQLException("", "08xxx", 666666666);
    DataAccessResourceFailureException darfFbt = (DataAccessResourceFailureException) sext.translate("task", "SQL-FBT2", sexFbt2);
    assertThat(darfFbt.getCause()).isEqualTo(sexFbt2);
}
Also used : BadSqlGrammarException(org.springframework.jdbc.BadSqlGrammarException) TransientDataAccessResourceException(org.springframework.dao.TransientDataAccessResourceException) SQLException(java.sql.SQLException) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) PermissionDeniedDataAccessException(org.springframework.dao.PermissionDeniedDataAccessException) DataIntegrityViolationException(org.springframework.dao.DataIntegrityViolationException) QueryTimeoutException(org.springframework.dao.QueryTimeoutException) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) ConcurrencyFailureException(org.springframework.dao.ConcurrencyFailureException) RecoverableDataAccessException(org.springframework.dao.RecoverableDataAccessException) Test(org.junit.jupiter.api.Test)

Example 34 with InvalidDataAccessApiUsageException

use of org.springframework.dao.InvalidDataAccessApiUsageException in project spring-framework by spring-projects.

the class JdbcTemplateTests method testExecuteClosed.

@Test
public void testExecuteClosed() throws Exception {
    given(this.resultSet.next()).willReturn(true);
    given(this.callableStatement.execute()).willReturn(true);
    given(this.callableStatement.getUpdateCount()).willReturn(-1);
    SqlParameter param = new SqlReturnResultSet("", (RowCallbackHandler) rs -> {
        throw new InvalidDataAccessApiUsageException("");
    });
    assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(() -> this.template.call(conn -> conn.prepareCall("my query"), Collections.singletonList(param)));
    verify(this.resultSet).close();
    verify(this.callableStatement).close();
    verify(this.connection).close();
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) DataAccessException(org.springframework.dao.DataAccessException) Connection(java.sql.Connection) BatchUpdateException(java.sql.BatchUpdateException) LinkedCaseInsensitiveMap(org.springframework.util.LinkedCaseInsensitiveMap) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) UncategorizedSQLException(org.springframework.jdbc.UncategorizedSQLException) DatabaseMetaData(java.sql.DatabaseMetaData) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) ArrayList(java.util.ArrayList) SingleConnectionDataSource(org.springframework.jdbc.datasource.SingleConnectionDataSource) SQLException(java.sql.SQLException) SQLWarningException(org.springframework.jdbc.SQLWarningException) BDDMockito.given(org.mockito.BDDMockito.given) ResultSet(java.sql.ResultSet) Map(java.util.Map) DataSource(javax.sql.DataSource) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) SQLWarning(java.sql.SQLWarning) SQLErrorCodeSQLExceptionTranslator(org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator) CannotGetJdbcConnectionException(org.springframework.jdbc.CannotGetJdbcConnectionException) BDDMockito.willThrow(org.mockito.BDDMockito.willThrow) Mockito.atLeastOnce(org.mockito.Mockito.atLeastOnce) AbstractInterruptibleBatchPreparedStatementSetter(org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter) Mockito.times(org.mockito.Mockito.times) ConnectionProxy(org.springframework.jdbc.datasource.ConnectionProxy) PreparedStatement(java.sql.PreparedStatement) BadSqlGrammarException(org.springframework.jdbc.BadSqlGrammarException) Mockito.verify(org.mockito.Mockito.verify) Test(org.junit.jupiter.api.Test) List(java.util.List) Mockito.never(org.mockito.Mockito.never) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) SQLStateSQLExceptionTranslator(org.springframework.jdbc.support.SQLStateSQLExceptionTranslator) Collections(java.util.Collections) Mockito.reset(org.mockito.Mockito.reset) ResultSetMetaData(java.sql.ResultSetMetaData) Types(java.sql.Types) StringUtils(org.springframework.util.StringUtils) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) Test(org.junit.jupiter.api.Test)

Example 35 with InvalidDataAccessApiUsageException

use of org.springframework.dao.InvalidDataAccessApiUsageException in project spring-framework by spring-projects.

the class RdbmsOperation method validateParameters.

/**
 * Validate the parameters passed to an execute method based on declared parameters.
 * Subclasses should invoke this method before every {@code executeQuery()}
 * or {@code update()} method.
 * @param parameters the parameters supplied (may be {@code null})
 * @throws InvalidDataAccessApiUsageException if the parameters are invalid
 */
protected void validateParameters(@Nullable Object[] parameters) throws InvalidDataAccessApiUsageException {
    checkCompiled();
    int declaredInParameters = 0;
    for (SqlParameter param : this.declaredParameters) {
        if (param.isInputValueProvided()) {
            if (!supportsLobParameters() && (param.getSqlType() == Types.BLOB || param.getSqlType() == Types.CLOB)) {
                throw new InvalidDataAccessApiUsageException("BLOB or CLOB parameters are not allowed for this kind of operation");
            }
            declaredInParameters++;
        }
    }
    validateParameterCount((parameters != null ? parameters.length : 0), declaredInParameters);
}
Also used : SqlParameter(org.springframework.jdbc.core.SqlParameter) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException)

Aggregations

InvalidDataAccessApiUsageException (org.springframework.dao.InvalidDataAccessApiUsageException)39 ArrayList (java.util.ArrayList)7 Test (org.junit.jupiter.api.Test)7 SQLException (java.sql.SQLException)6 List (java.util.List)6 Map (java.util.Map)6 Document (org.bson.Document)6 Collections (java.util.Collections)5 DataAccessException (org.springframework.dao.DataAccessException)5 Connection (java.sql.Connection)4 ResultSet (java.sql.ResultSet)4 Arrays (java.util.Arrays)4 SqlParameter (org.springframework.jdbc.core.SqlParameter)4 StringUtils (org.springframework.util.StringUtils)4 MongoPersistentProperty (org.springframework.data.mongodb.core.mapping.MongoPersistentProperty)3 FullDocument (com.mongodb.client.model.changestream.FullDocument)2 PreparedStatement (java.sql.PreparedStatement)2 ResultSetMetaData (java.sql.ResultSetMetaData)2 Statement (java.sql.Statement)2 DataSource (javax.sql.DataSource)2