Backport further refinements from the nullability efforts
Issue: SPR-15656
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,20 +25,21 @@ import java.util.List;
|
||||
* within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class BatchUpdateUtils {
|
||||
|
||||
public static int[] executeBatchUpdate(String sql, final List<Object[]> batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) {
|
||||
public static int[] executeBatchUpdate(
|
||||
String sql, final List<Object[]> batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) {
|
||||
|
||||
return jdbcOperations.batchUpdate(
|
||||
sql,
|
||||
new BatchPreparedStatementSetter() {
|
||||
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
Object[] values = batchValues.get(i);
|
||||
setStatementParameters(values, ps, columnTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return batchValues.size();
|
||||
@@ -46,7 +47,9 @@ public abstract class BatchUpdateUtils {
|
||||
});
|
||||
}
|
||||
|
||||
protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) throws SQLException {
|
||||
protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes)
|
||||
throws SQLException {
|
||||
|
||||
int colIndex = 0;
|
||||
for (Object value : values) {
|
||||
colIndex++;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1267,11 +1267,14 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||
* @param param the corresponding stored procedure parameter
|
||||
* @return Map that contains returned results
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
protected Map<String, Object> processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException {
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected Map<String, Object> processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param)
|
||||
throws SQLException {
|
||||
|
||||
if (rs == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, Object> returnedResults = new HashMap<String, Object>();
|
||||
try {
|
||||
ResultSet rsToUse = rs;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -119,7 +119,7 @@ public abstract class StatementCreatorUtils {
|
||||
/**
|
||||
* Derive a default SQL type from the given Java type.
|
||||
* @param javaType the Java type to translate
|
||||
* @return the corresponding SQL type, or {@code null} if none found
|
||||
* @return the corresponding SQL type, or {@link SqlTypeValue#TYPE_UNKNOWN} if none found
|
||||
*/
|
||||
public static int javaTypeToSqlParameterType(Class<?> javaType) {
|
||||
Integer sqlType = javaTypeToSqlTypeMap.get(javaType);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -234,6 +234,14 @@ public class CallMetaDataContext {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize this class with metadata from the database.
|
||||
* @param dataSource the DataSource used to retrieve metadata
|
||||
*/
|
||||
public void initializeMetaData(DataSource dataSource) {
|
||||
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
|
||||
* by the JDBC driver used for the database in use.
|
||||
@@ -278,14 +286,6 @@ public class CallMetaDataContext {
|
||||
return this.callParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this class with metadata from the database.
|
||||
* @param dataSource the DataSource used to retrieve metadata
|
||||
*/
|
||||
public void initializeMetaData(DataSource dataSource) {
|
||||
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the list of parameters provided, and if procedure column metadata is used,
|
||||
* the parameters will be matched against the metadata information and any missing
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,9 +51,8 @@ public interface CallMetaDataProvider {
|
||||
* @throws SQLException in case of initialization failure
|
||||
* @see org.springframework.jdbc.core.simple.SimpleJdbcCall#withoutProcedureColumnMetaDataAccess()
|
||||
*/
|
||||
void initializeWithProcedureColumnMetaData(
|
||||
DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName)
|
||||
throws SQLException;
|
||||
void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName,
|
||||
String schemaName, String procedureName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Provide any modification of the procedure name passed in to match the meta data currently used.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,8 +21,8 @@ import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* The Derby specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}.
|
||||
* Overrides the Derby metadata info regarding retreiving generated keys. It seems to work OK so not sure why they
|
||||
* claim it's not supported.
|
||||
* Overrides the Derby metadata info regarding retrieving generated keys. It seems to work OK so not sure why
|
||||
* they claim it's not supported.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @since 3.0
|
||||
@@ -31,26 +31,26 @@ public class DerbyTableMetaDataProvider extends GenericTableMetaDataProvider {
|
||||
|
||||
private boolean supportsGeneratedKeysOverride = false;
|
||||
|
||||
|
||||
public DerbyTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
super(databaseMetaData);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
super.initializeWithMetaData(databaseMetaData);
|
||||
if (!databaseMetaData.supportsGetGeneratedKeys()) {
|
||||
logger.warn("Overriding supportsGetGeneratedKeys from DatabaseMetaData to 'true'; it was reported as " +
|
||||
"'false' by " + databaseMetaData.getDriverName() + " " + databaseMetaData.getDriverVersion());
|
||||
supportsGeneratedKeysOverride = true;
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Overriding supportsGetGeneratedKeys from DatabaseMetaData to 'true'; it was reported as " +
|
||||
"'false' by " + databaseMetaData.getDriverName() + " " + databaseMetaData.getDriverVersion());
|
||||
}
|
||||
this.supportsGeneratedKeysOverride = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGetGeneratedKeysSupported() {
|
||||
boolean derbysAnswer = super.isGetGeneratedKeysSupported();
|
||||
if (!derbysAnswer) {
|
||||
return supportsGeneratedKeysOverride;
|
||||
}
|
||||
return derbysAnswer;
|
||||
return (super.isGetGeneratedKeysSupported() || this.supportsGeneratedKeysOverride);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
/**
|
||||
* Oracle specific implementation for the {@link CallMetaDataProvider} interface.
|
||||
* Oracle-specific implementation for the {@link CallMetaDataProvider} interface.
|
||||
* This class is intended for internal use by the Simple JDBC classes.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
@@ -59,13 +59,13 @@ public class OracleCallMetaDataProvider extends GenericCallMetaDataProvider {
|
||||
@Override
|
||||
public String metaDataCatalogNameToUse(String catalogName) {
|
||||
// Oracle uses catalog name for package name or an empty string if no package
|
||||
return catalogName == null ? "" : catalogNameToUse(catalogName);
|
||||
return (catalogName == null ? "" : catalogNameToUse(catalogName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String metaDataSchemaNameToUse(String schemaName) {
|
||||
// Use current user schema if no schema specified
|
||||
return schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName);
|
||||
return (schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import org.springframework.jdbc.core.SqlOutParameter;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
/**
|
||||
* Oracle specific implementation for the {@link org.springframework.jdbc.core.metadata.CallMetaDataProvider} interface.
|
||||
* Postgres-specific implementation for the {@link CallMetaDataProvider} interface.
|
||||
* This class is intended for internal use by the Simple JDBC classes.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
@@ -59,7 +59,7 @@ public class PostgresCallMetaDataProvider extends GenericCallMetaDataProvider {
|
||||
@Override
|
||||
public String metaDataSchemaNameToUse(String schemaName) {
|
||||
// Use public schema if no schema specified
|
||||
return schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName);
|
||||
return (schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +74,7 @@ public class PostgresCallMetaDataProvider extends GenericCallMetaDataProvider {
|
||||
|
||||
@Override
|
||||
public boolean byPassReturnParameter(String parameterName) {
|
||||
return (RETURN_VALUE_NAME.equals(parameterName) ||
|
||||
super.byPassReturnParameter(parameterName));
|
||||
return RETURN_VALUE_NAME.equals(parameterName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -90,8 +90,7 @@ public class SqlParameterSourceUtils {
|
||||
Map<String, String> caseInsensitiveParameterNames = new HashMap<String, String>();
|
||||
if (parameterSource instanceof BeanPropertySqlParameterSource) {
|
||||
String[] propertyNames = ((BeanPropertySqlParameterSource)parameterSource).getReadablePropertyNames();
|
||||
for (int i = 0; i < propertyNames.length; i++) {
|
||||
String name = propertyNames[i];
|
||||
for (String name : propertyNames) {
|
||||
caseInsensitiveParameterNames.put(name.toLowerCase(), name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
|
||||
@Override
|
||||
protected boolean isExistingTransaction(Object transaction) {
|
||||
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
|
||||
return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
|
||||
return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +241,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
|
||||
Connection con = null;
|
||||
|
||||
try {
|
||||
if (txObject.getConnectionHolder() == null ||
|
||||
if (!txObject.hasConnectionHolder() ||
|
||||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
|
||||
Connection newCon = this.dataSource.getConnection();
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -268,8 +268,10 @@ public abstract class DataSourceUtils {
|
||||
*/
|
||||
public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout) throws SQLException {
|
||||
Assert.notNull(stmt, "No Statement specified");
|
||||
Assert.notNull(dataSource, "No DataSource specified");
|
||||
ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
|
||||
ConnectionHolder holder = null;
|
||||
if (dataSource != null) {
|
||||
holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
|
||||
}
|
||||
if (holder != null && holder.hasTimeout()) {
|
||||
// Remaining transaction timeout overrides specified value.
|
||||
stmt.setQueryTimeout(holder.getTimeToLiveInSeconds());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,10 +54,8 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link DatabasePopulator} to execute during the bean initialization
|
||||
* phase.
|
||||
* @param databasePopulator the {@code DatabasePopulator} to use during
|
||||
* initialization
|
||||
* Set the {@link DatabasePopulator} to execute during the bean initialization phase.
|
||||
* @param databasePopulator the {@code DatabasePopulator} to use during initialization
|
||||
* @see #setDatabaseCleaner
|
||||
*/
|
||||
public void setDatabasePopulator(DatabasePopulator databasePopulator) {
|
||||
@@ -84,6 +82,7 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use the {@linkplain #setDatabasePopulator database populator} to set up
|
||||
* the database.
|
||||
@@ -103,7 +102,7 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean {
|
||||
}
|
||||
|
||||
private void execute(DatabasePopulator populator) {
|
||||
Assert.state(dataSource != null, "DataSource must be set");
|
||||
Assert.state(this.dataSource != null, "DataSource must be set");
|
||||
if (this.enabled && populator != null) {
|
||||
DatabasePopulatorUtils.execute(populator, this.dataSource);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -48,9 +48,7 @@ public abstract class DatabasePopulatorUtils {
|
||||
populator.populate(connection);
|
||||
}
|
||||
finally {
|
||||
if (connection != null) {
|
||||
DataSourceUtils.releaseConnection(connection, dataSource);
|
||||
}
|
||||
DataSourceUtils.releaseConnection(connection, dataSource);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An "RDBMS operation" is a multi-threaded, reusable object representing a query,
|
||||
@@ -85,27 +86,25 @@ public abstract class RdbmsOperation implements InitializingBean {
|
||||
|
||||
|
||||
/**
|
||||
* An alternative to the more commonly used setDataSource() when you want to
|
||||
* use the same JdbcTemplate in multiple RdbmsOperations. This is appropriate if the
|
||||
* JdbcTemplate has special configuration such as a SQLExceptionTranslator that should
|
||||
* apply to multiple RdbmsOperation objects.
|
||||
* An alternative to the more commonly used {@link #setDataSource} when you want to
|
||||
* use the same {@link JdbcTemplate} in multiple {@code RdbmsOperations}. This is
|
||||
* appropriate if the {@code JdbcTemplate} has special configuration such as a
|
||||
* {@link org.springframework.jdbc.support.SQLExceptionTranslator} to be reused.
|
||||
*/
|
||||
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
|
||||
if (jdbcTemplate == null) {
|
||||
throw new IllegalArgumentException("jdbcTemplate must not be null");
|
||||
}
|
||||
Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null");
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JdbcTemplate object used by this object.
|
||||
* Return the {@link JdbcTemplate} used by this operation object.
|
||||
*/
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JDBC DataSource to obtain connections from.
|
||||
* Set the JDBC {@link DataSource} to obtain connections from.
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#setDataSource
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
@@ -233,9 +232,8 @@ public abstract class RdbmsOperation implements InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this to supply dynamic SQL if they wish,
|
||||
* but SQL is normally set by calling the setSql() method
|
||||
* or in a subclass constructor.
|
||||
* Subclasses can override this to supply dynamic SQL if they wish, but SQL is
|
||||
* normally set by calling the {@link #setSql} method or in a subclass constructor.
|
||||
*/
|
||||
public String getSql() {
|
||||
return this.sql;
|
||||
@@ -287,7 +285,7 @@ public abstract class RdbmsOperation implements InitializingBean {
|
||||
* @param parameters Array containing the declared {@link SqlParameter} objects
|
||||
* @see #declaredParameters
|
||||
*/
|
||||
public void setParameters(SqlParameter[] parameters) {
|
||||
public void setParameters(SqlParameter... parameters) {
|
||||
if (isCompiled()) {
|
||||
throw new InvalidDataAccessApiUsageException("Cannot add parameters once the query is compiled");
|
||||
}
|
||||
@@ -396,7 +394,7 @@ public abstract class RdbmsOperation implements InitializingBean {
|
||||
* Validate the named 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 parameter Map supplied. May be {@code null}.
|
||||
* @param parameters parameter Map supplied (may be {@code null})
|
||||
* @throws InvalidDataAccessApiUsageException if the parameters are invalid
|
||||
*/
|
||||
protected void validateNamedParameters(Map<String, ?> parameters) throws InvalidDataAccessApiUsageException {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -70,16 +70,22 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
|
||||
sql = "";
|
||||
}
|
||||
|
||||
DataAccessException dex = doTranslate(task, sql, ex);
|
||||
if (dex != null) {
|
||||
DataAccessException dae = doTranslate(task, sql, ex);
|
||||
if (dae != null) {
|
||||
// Specific exception match found.
|
||||
return dex;
|
||||
return dae;
|
||||
}
|
||||
|
||||
// Looking for a fallback...
|
||||
SQLExceptionTranslator fallback = getFallbackTranslator();
|
||||
if (fallback != null) {
|
||||
return fallback.translate(task, sql, ex);
|
||||
dae = fallback.translate(task, sql, ex);
|
||||
if (dae != null) {
|
||||
// Fallback exception match found.
|
||||
return dae;
|
||||
}
|
||||
}
|
||||
|
||||
// We couldn't identify it more precisely.
|
||||
return new UncategorizedSQLException(task, sql, ex);
|
||||
}
|
||||
@@ -90,7 +96,7 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
|
||||
* is allowed to return {@code null} to indicate that no exception match has
|
||||
* been found and that fallback translation should kick in.
|
||||
* @param task readable text describing the task being attempted
|
||||
* @param sql SQL query or update that caused the problem (may be {@code null})
|
||||
* @param sql SQL query or update that caused the problem (if known)
|
||||
* @param ex the offending {@code SQLException}
|
||||
* @return the DataAccessException, wrapping the {@code SQLException};
|
||||
* or {@code null} if no exception match found
|
||||
@@ -103,7 +109,7 @@ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExcep
|
||||
* <p>To be called by translator subclasses when creating an instance of a generic
|
||||
* {@link org.springframework.dao.DataAccessException} class.
|
||||
* @param task readable text describing the task being attempted
|
||||
* @param sql the SQL statement that caused the problem (may be {@code null})
|
||||
* @param sql the SQL statement that caused the problem
|
||||
* @param ex the offending {@code SQLException}
|
||||
* @return the message {@code String} to use
|
||||
*/
|
||||
|
||||
@@ -472,8 +472,8 @@ public abstract class JdbcUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a column name with underscores to the corresponding property name using "camel case". A name
|
||||
* like "customer_number" would match a "customerNumber" property name.
|
||||
* Convert a column name with underscores to the corresponding property name using "camel case".
|
||||
* A name like "customer_number" would match a "customerNumber" property name.
|
||||
* @param name the column name to be converted
|
||||
* @return the name using "camel case"
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -216,9 +216,9 @@ public class SQLErrorCodesFactory {
|
||||
}
|
||||
catch (MetaDataAccessException ex) {
|
||||
logger.warn("Error while extracting database name - falling back to empty error codes", ex);
|
||||
// Fallback is to return an empty SQLErrorCodes instance.
|
||||
return new SQLErrorCodes();
|
||||
}
|
||||
// Fallback is to return an empty SQLErrorCodes instance.
|
||||
return new SQLErrorCodes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,11 +59,15 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
public void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content)
|
||||
throws SQLException {
|
||||
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
blob.setBytes(1, content);
|
||||
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
if (content != null) {
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
blob.setBytes(1, content);
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
}
|
||||
else {
|
||||
ps.setBlob(paramIndex, (Blob) null);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(content != null ? "Copied bytes into temporary BLOB with length " + content.length :
|
||||
@@ -76,17 +80,21 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
PreparedStatement ps, int paramIndex, InputStream binaryStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
try {
|
||||
FileCopyUtils.copy(binaryStream, blob.setBinaryStream(1));
|
||||
if (binaryStream != null) {
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
try {
|
||||
FileCopyUtils.copy(binaryStream, blob.setBinaryStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
else {
|
||||
ps.setBlob(paramIndex, (Blob) null);
|
||||
}
|
||||
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(binaryStream != null ?
|
||||
"Copied binary stream into temporary BLOB with length " + contentLength :
|
||||
@@ -98,11 +106,15 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
public void setClobAsString(PreparedStatement ps, int paramIndex, String content)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
clob.setString(1, content);
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
if (content != null) {
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
clob.setString(1, content);
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(content != null ? "Copied string into temporary CLOB with length " + content.length() :
|
||||
@@ -115,17 +127,21 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(asciiStream, clob.setAsciiStream(1));
|
||||
if (asciiStream != null) {
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(asciiStream, clob.setAsciiStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
}
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(asciiStream != null ?
|
||||
"Copied ASCII stream into temporary CLOB with length " + contentLength :
|
||||
@@ -138,17 +154,21 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(characterStream, clob.setCharacterStream(1));
|
||||
if (characterStream != null) {
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(characterStream, clob.setCharacterStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
}
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(characterStream != null ?
|
||||
"Copied character stream into temporary CLOB with length " + contentLength :
|
||||
@@ -170,4 +190,5 @@ public class TemporaryLobCreator implements LobCreator {
|
||||
logger.error("Could not free LOB", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user