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.
}
}
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");
}
}
}
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);
}
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();
}
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);
}
Aggregations