@Nullable all the way: null-safety at field level

This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.

Issue: SPR-15720
This commit is contained in:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -60,7 +60,7 @@ public class SortedResourcesFactoryBean extends AbstractFactoryBean<Resource[]>
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
}

View File

@@ -29,6 +29,7 @@ import org.springframework.lang.Nullable;
*/
public class ArgumentPreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer {
@Nullable
private final Object[] args;

View File

@@ -33,8 +33,10 @@ import org.springframework.lang.Nullable;
*/
public class ArgumentTypePreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer {
@Nullable
private final Object[] args;
@Nullable
private final int[] argTypes;

View File

@@ -80,6 +80,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
protected final Log logger = LogFactory.getLog(getClass());
/** The class we are mapping to */
@Nullable
private Class<T> mappedClass;
/** Whether we're strictly validating */
@@ -89,12 +90,15 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
private boolean primitivesDefaultedForNullValue = false;
/** ConversionService for binding JDBC values to bean properties */
@Nullable
private ConversionService conversionService = DefaultConversionService.getSharedInstance();
/** Map of the fields we provide mapping for */
@Nullable
private Map<String, PropertyDescriptor> mappedFields;
/** Set of bean properties we provide mapping for */
@Nullable
private Set<String> mappedProperties;
@@ -147,6 +151,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/**
* Get the class that we are mapping to.
*/
@Nullable
public final Class<T> getMappedClass() {
return this.mappedClass;
}
@@ -287,7 +292,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
for (int index = 1; index <= columnCount; index++) {
String column = JdbcUtils.lookupColumnName(rsmd, index);
String field = lowerCaseName(column.replaceAll(" ", ""));
PropertyDescriptor pd = this.mappedFields.get(field);
PropertyDescriptor pd = (this.mappedFields != null ? this.mappedFields.get(field) : null);
if (pd != null) {
try {
Object value = getColumnValue(rs, index, pd);

View File

@@ -121,8 +121,10 @@ public class CallableStatementCreatorFactory {
*/
private class CallableStatementCreatorImpl implements CallableStatementCreator, SqlProvider, ParameterDisposer {
@Nullable
private ParameterMapper inParameterMapper;
@Nullable
private Map<String, ?> inParameters;
/**

View File

@@ -56,7 +56,8 @@ public class PreparedStatementCreatorFactory {
private boolean returnGeneratedKeys = false;
private String[] generatedKeysColumnNames = null;
@Nullable
private String[] generatedKeysColumnNames;
/**

View File

@@ -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.
@@ -27,10 +27,13 @@ import org.springframework.lang.Nullable;
*/
public class ResultSetSupportingSqlParameter extends SqlParameter {
@Nullable
private ResultSetExtractor<?> resultSetExtractor;
@Nullable
private RowCallbackHandler rowCallbackHandler;
@Nullable
private RowMapper<?> rowMapper;

View File

@@ -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.
@@ -43,6 +43,7 @@ import org.springframework.util.NumberUtils;
*/
public class SingleColumnRowMapper<T> implements RowMapper<T> {
@Nullable
private Class<?> requiredType;

View File

@@ -34,6 +34,7 @@ import org.springframework.lang.Nullable;
*/
public class SqlOutParameter extends ResultSetSupportingSqlParameter {
@Nullable
private SqlReturnType sqlReturnType;

View File

@@ -36,15 +36,18 @@ import org.springframework.util.Assert;
public class SqlParameter {
/** The name of the parameter, if any */
@Nullable
private String name;
/** SQL type constant from {@code java.sql.Types} */
private final int sqlType;
/** Used for types that are user-named like: STRUCT, DISTINCT, JAVA_OBJECT, named array types */
@Nullable
private String typeName;
/** The scale to apply in case of a NUMERIC or DECIMAL type, if any */
@Nullable
private Integer scale;

View File

@@ -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.
@@ -38,6 +38,7 @@ import org.springframework.lang.Nullable;
*/
public class SqlParameterValue extends SqlParameter {
@Nullable
private final Object value;
@@ -88,6 +89,7 @@ public class SqlParameterValue extends SqlParameter {
/**
* Return the value object that this parameter value holds.
*/
@Nullable
public Object getValue() {
return this.value;
}

View File

@@ -141,8 +141,8 @@ public abstract class StatementCreatorUtils {
* @param inValue the value to set
* @throws SQLException if thrown by PreparedStatement methods
*/
public static void setParameterValue(PreparedStatement ps, int paramIndex, SqlParameter param, Object inValue)
throws SQLException {
public static void setParameterValue(PreparedStatement ps, int paramIndex, SqlParameter param,
@Nullable Object inValue) throws SQLException {
setParameterValueInternal(ps, paramIndex, param.getSqlType(), param.getTypeName(), param.getScale(), inValue);
}
@@ -157,8 +157,8 @@ public abstract class StatementCreatorUtils {
* @throws SQLException if thrown by PreparedStatement methods
* @see SqlTypeValue
*/
public static void setParameterValue(PreparedStatement ps, int paramIndex, int sqlType, Object inValue)
throws SQLException {
public static void setParameterValue(PreparedStatement ps, int paramIndex, int sqlType,
@Nullable Object inValue) throws SQLException {
setParameterValueInternal(ps, paramIndex, sqlType, null, null, inValue);
}
@@ -176,7 +176,7 @@ public abstract class StatementCreatorUtils {
* @see SqlTypeValue
*/
public static void setParameterValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName,
Object inValue) throws SQLException {
@Nullable Object inValue) throws SQLException {
setParameterValueInternal(ps, paramIndex, sqlType, typeName, null, inValue);
}

View File

@@ -40,6 +40,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -56,18 +57,22 @@ public class CallMetaDataContext {
protected final Log logger = LogFactory.getLog(getClass());
/** name of procedure to call **/
@Nullable
private String procedureName;
/** name of catalog for call **/
@Nullable
private String catalogName;
/** name of schema for call **/
@Nullable
private String schemaName;
/** List of SqlParameter objects to be used in call execution */
private List<SqlParameter> callParameters = new ArrayList<>();
/** Actual name to use for the return value in the output map */
@Nullable
private String actualFunctionReturnName;
/** Set of in parameter names to exclude use for any not listed */
@@ -89,6 +94,7 @@ public class CallMetaDataContext {
private boolean namedBinding;
/** The provider of call meta data */
@Nullable
private CallMetaDataProvider metaDataProvider;
@@ -246,6 +252,7 @@ public class CallMetaDataContext {
* @return the appropriate SqlParameter
*/
public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
if (this.metaDataProvider.isReturnResultSetSupported()) {
return new SqlReturnResultSet(parameterName, rowMapper);
}
@@ -305,6 +312,8 @@ public class CallMetaDataContext {
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
*/
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
final List<SqlParameter> declaredReturnParams = new ArrayList<>();
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
boolean returnDeclared = false;
@@ -464,6 +473,8 @@ public class CallMetaDataContext {
* @return a Map containing the matched parameter names with the value taken from the input
*/
public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
// For parameter source lookups we need to provide case-insensitive lookup support
// since the database metadata is not necessarily providing case sensitive parameter names.
Map<String, String> caseInsensitiveParameterNames =
@@ -527,9 +538,11 @@ public class CallMetaDataContext {
* @return a Map containing the matched parameter names with the value taken from the input
*/
public Map<String, ?> matchInParameterValuesWithCallParameters(Map<String, ?> inParameters) {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
return inParameters;
}
Map<String, String> callParameterNames = new HashMap<>(this.callParameters.size());
for (SqlParameter parameter : this.callParameters) {
if (parameter.isInputValueProvided()) {
@@ -540,6 +553,7 @@ public class CallMetaDataContext {
}
}
}
Map<String, Object> matchedParameters = new HashMap<>(inParameters.size());
for (String parameterName : inParameters.keySet()) {
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
@@ -560,6 +574,7 @@ public class CallMetaDataContext {
matchedParameters.put(callParameterName, inParameters.get(parameterName));
}
}
if (matchedParameters.size() < callParameterNames.size()) {
for (String parameterName : callParameterNames.keySet()) {
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
@@ -570,6 +585,7 @@ public class CallMetaDataContext {
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("Matching " + inParameters.keySet() + " with " + callParameterNames.values());
logger.debug("Found match for " + matchedParameters.keySet());
@@ -594,6 +610,8 @@ public class CallMetaDataContext {
* @return the call string to be used
*/
public String createCallString() {
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
String callString;
int parameterCount = 0;
String catalogNameToUse;
@@ -610,6 +628,7 @@ public class CallMetaDataContext {
catalogNameToUse = this.metaDataProvider.catalogNameToUse(getCatalogName());
schemaNameToUse = this.metaDataProvider.schemaNameToUse(getSchemaName());
}
String procedureNameToUse = this.metaDataProvider.procedureNameToUse(getProcedureName());
if (isFunction() || isReturnValueRequired()) {
callString = "{? = call " +
@@ -624,6 +643,7 @@ public class CallMetaDataContext {
(StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") +
procedureNameToUse + "(";
}
for (SqlParameter parameter : this.callParameters) {
if (!(parameter.isResultsParameter())) {
if (parameterCount > 0) {

View File

@@ -27,12 +27,14 @@ import org.springframework.lang.Nullable;
*/
public class CallParameterMetaData {
@Nullable
private String parameterName;
private int parameterType;
private int sqlType;
@Nullable
private String typeName;
private boolean nullable;

View File

@@ -50,9 +50,11 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
private boolean tableColumnMetaDataUsed = false;
/** the version of the database */
@Nullable
private String databaseVersion;
/** the name of the user currently connected */
@Nullable
private String userName;
/** indicates whether the identifiers are uppercased */
@@ -209,7 +211,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers': " + ex.getMessage());
}
}
}
@Override
@@ -284,6 +285,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
/**
* Provide access to default schema for subclasses.
*/
@Nullable
protected String getDefaultSchema() {
return this.userName;
}
@@ -291,6 +293,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
/**
* Provide access to version info for subclasses.
*/
@Nullable
protected String getDatabaseVersion() {
return this.databaseVersion;
}
@@ -427,10 +430,13 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
*/
private static class TableMetaData {
@Nullable
private String catalogName;
@Nullable
private String schemaName;
@Nullable
private String tableName;
public void setCatalogName(String catalogName) {

View File

@@ -43,6 +43,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
private final boolean includeSynonyms;
@Nullable
private String defaultSchema;
@@ -104,7 +105,8 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
@Override
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
@Nullable String catalogName, @Nullable String schemaName, String tableName) throws SQLException {
@Nullable String catalogName, @Nullable String schemaName, @Nullable String tableName)
throws SQLException {
if (!this.includeSynonyms) {
logger.debug("Defaulting to no synonyms in table metadata lookup");

View File

@@ -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.
@@ -35,13 +35,14 @@ public class PostgresTableMetaDataProvider extends GenericTableMetaDataProvider
@Override
public boolean isGetGeneratedKeysSimulated() {
if (getDatabaseVersion().compareTo("8.2.0") >= 0) {
String version = getDatabaseVersion();
if (version != null && version.compareTo("8.2.0") >= 0) {
return true;
}
else {
if (logger.isWarnEnabled()) {
logger.warn("PostgreSQL does not support getGeneratedKeys or INSERT ... RETURNING in version " +
getDatabaseVersion());
version);
}
return false;
}

View File

@@ -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.
@@ -25,6 +25,7 @@ import org.springframework.beans.NotReadablePropertyException;
import org.springframework.beans.PropertyAccessor;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.jdbc.core.StatementCreatorUtils;
import org.springframework.lang.Nullable;
/**
* {@link SqlParameterSource} implementation that obtains parameter values
@@ -43,6 +44,7 @@ public class BeanPropertySqlParameterSource extends AbstractSqlParameterSource {
private final BeanWrapper beanWrapper;
@Nullable
private String[] propertyNames;

View File

@@ -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.
@@ -16,7 +16,9 @@
package org.springframework.jdbc.core.namedparam;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.lang.Nullable;
/**
* Extension of JdbcDaoSupport that exposes a NamedParameterJdbcTemplate as well.
@@ -28,6 +30,7 @@ import org.springframework.jdbc.core.support.JdbcDaoSupport;
*/
public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport {
@Nullable
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@@ -36,14 +39,18 @@ public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport {
*/
@Override
protected void initTemplateConfig() {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
JdbcTemplate jdbcTemplate = getJdbcTemplate();
if (jdbcTemplate != null) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
}
}
/**
* Return a NamedParameterJdbcTemplate wrapping the configured JdbcTemplate.
*/
@Nullable
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return namedParameterJdbcTemplate;
return this.namedParameterJdbcTemplate;
}
}

View File

@@ -24,6 +24,7 @@ import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -45,6 +46,7 @@ import org.springframework.util.Assert;
*/
public abstract class JdbcDaoSupport extends DaoSupport {
@Nullable
private JdbcTemplate jdbcTemplate;
@@ -91,6 +93,7 @@ public abstract class JdbcDaoSupport extends DaoSupport {
* Return the JdbcTemplate for this DAO,
* pre-initialized with the DataSource or set explicitly.
*/
@Nullable
public final JdbcTemplate getJdbcTemplate() {
return this.jdbcTemplate;
}
@@ -120,7 +123,9 @@ public abstract class JdbcDaoSupport extends DaoSupport {
* @see org.springframework.jdbc.core.JdbcTemplate#getExceptionTranslator()
*/
protected final SQLExceptionTranslator getExceptionTranslator() {
return getJdbcTemplate().getExceptionTranslator();
JdbcTemplate jdbcTemplate = getJdbcTemplate();
Assert.state(jdbcTemplate != null, "No JdbcTemplate set");
return jdbcTemplate.getExceptionTranslator();
}
/**

View File

@@ -66,6 +66,7 @@ import org.springframework.lang.Nullable;
*/
public class SqlLobValue implements DisposableSqlTypeValue {
@Nullable
private final Object content;
private final int length;

View File

@@ -34,16 +34,22 @@ import org.springframework.util.Assert;
*/
public abstract class AbstractDriverBasedDataSource extends AbstractDataSource {
@Nullable
private String url;
@Nullable
private String username;
@Nullable
private String password;
@Nullable
private String catalog;
@Nullable
private String schema;
@Nullable
private Properties connectionProperties;

View File

@@ -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.
@@ -44,12 +44,15 @@ public class ConnectionHolder extends ResourceHolderSupport {
public static final String SAVEPOINT_NAME_PREFIX = "SAVEPOINT_";
@Nullable
private ConnectionHandle connectionHandle;
@Nullable
private Connection currentConnection;
private boolean transactionActive = false;
@Nullable
private Boolean savepointsSupported;
private int savepointCounter = 0;
@@ -93,6 +96,7 @@ public class ConnectionHolder extends ResourceHolderSupport {
/**
* Return the ConnectionHandle held by this ConnectionHolder.
*/
@Nullable
public ConnectionHandle getConnectionHandle() {
return this.connectionHandle;
}
@@ -128,7 +132,9 @@ public class ConnectionHolder extends ResourceHolderSupport {
*/
protected void setConnection(@Nullable Connection connection) {
if (this.currentConnection != null) {
this.connectionHandle.releaseConnection(this.currentConnection);
if (this.connectionHandle != null) {
this.connectionHandle.releaseConnection(this.currentConnection);
}
this.currentConnection = null;
}
if (connection != null) {
@@ -189,7 +195,9 @@ public class ConnectionHolder extends ResourceHolderSupport {
public void released() {
super.released();
if (!isOpen() && this.currentConnection != null) {
this.connectionHandle.releaseConnection(this.currentConnection);
if (this.connectionHandle != null) {
this.connectionHandle.releaseConnection(this.currentConnection);
}
this.currentConnection = null;
}
}

View File

@@ -112,6 +112,7 @@ import org.springframework.util.Assert;
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
@Nullable
private DataSource dataSource;
private boolean enforceReadOnly = false;
@@ -236,7 +237,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
@@ -298,7 +299,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, this.dataSource);
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
@@ -309,12 +310,12 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
protected Object doSuspend(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
txObject.setConnectionHolder(null);
return TransactionSynchronizationManager.unbindResource(this.dataSource);
return TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
@Override
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
TransactionSynchronizationManager.bindResource(this.dataSource, suspendedResources);
TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}
@Override
@@ -363,7 +364,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
// Remove the connection holder from the thread, if exposed.
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(this.dataSource);
TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
// Reset connection.

View File

@@ -58,6 +58,7 @@ public class IsolationLevelDataSourceAdapter extends UserCredentialsDataSourceAd
/** Constants instance for TransactionDefinition */
private static final Constants constants = new Constants(TransactionDefinition.class);
@Nullable
private Integer isolationLevel;

View File

@@ -51,8 +51,10 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager,
private static final Log logger = LogFactory.getLog(JdbcTransactionObjectSupport.class);
@Nullable
private ConnectionHolder connectionHolder;
@Nullable
private Integer previousIsolationLevel;
private boolean savepointAllowed = false;
@@ -75,6 +77,7 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager,
this.previousIsolationLevel = previousIsolationLevel;
}
@Nullable
public Integer getPreviousIsolationLevel() {
return this.previousIsolationLevel;
}

View File

@@ -83,8 +83,10 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
private static final Log logger = LogFactory.getLog(LazyConnectionDataSourceProxy.class);
@Nullable
private Boolean defaultAutoCommit;
@Nullable
private Integer defaultTransactionIsolation;
@@ -193,6 +195,7 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
/**
* Expose the default auto-commit value.
*/
@Nullable
protected Boolean defaultAutoCommit() {
return this.defaultAutoCommit;
}
@@ -200,6 +203,7 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
/**
* Expose the default transaction isolation value.
*/
@Nullable
protected Integer defaultTransactionIsolation() {
return this.defaultTransactionIsolation;
}
@@ -246,18 +250,23 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
*/
private class LazyConnectionInvocationHandler implements InvocationHandler {
@Nullable
private String username;
@Nullable
private String password;
private Boolean readOnly = Boolean.FALSE;
private Integer transactionIsolation;
@Nullable
private Boolean autoCommit;
@Nullable
private Integer transactionIsolation;
private boolean closed = false;
@Nullable
private Connection target;
public LazyConnectionInvocationHandler() {

View File

@@ -58,12 +58,15 @@ public class SingleConnectionDataSource extends DriverManagerDataSource implemen
private boolean suppressClose;
/** Override auto-commit state? */
@Nullable
private Boolean autoCommit;
/** Wrapped Connection */
@Nullable
private Connection target;
/** Proxy Connection */
@Nullable
private Connection connection;
/** Synchronization monitor for the shared Connection */

View File

@@ -160,6 +160,7 @@ public class TransactionAwareDataSourceProxy extends DelegatingDataSource {
private final DataSource targetDataSource;
@Nullable
private Connection target;
private boolean closed = false;

View File

@@ -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.
@@ -20,6 +20,7 @@ import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -61,12 +62,16 @@ import org.springframework.util.StringUtils;
*/
public class UserCredentialsDataSourceAdapter extends DelegatingDataSource {
@Nullable
private String username;
@Nullable
private String password;
@Nullable
private String catalog;
@Nullable
private String schema;
private final ThreadLocal<JdbcUserCredentials> threadBoundCredentials =
@@ -183,7 +188,7 @@ public class UserCredentialsDataSourceAdapter extends DelegatingDataSource {
* @see javax.sql.DataSource#getConnection(String, String)
* @see javax.sql.DataSource#getConnection()
*/
protected Connection doGetConnection(String username, String password) throws SQLException {
protected Connection doGetConnection(@Nullable String username, @Nullable String password) throws SQLException {
Assert.state(getTargetDataSource() != null, "'targetDataSource' is required");
if (StringUtils.hasLength(username)) {
return getTargetDataSource().getConnection(username, password);

View File

@@ -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.
@@ -23,6 +23,8 @@ import javax.sql.DataSource;
import org.apache.commons.logging.LogFactory;
import org.apache.derby.jdbc.EmbeddedDriver;
import org.springframework.lang.Nullable;
/**
* {@link EmbeddedDatabaseConfigurer} for the Apache Derby database 10.6+.
* <p>Call {@link #getInstance()} to get the singleton instance of this class.
@@ -35,6 +37,7 @@ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigure
private static final String URL_TEMPLATE = "jdbc:derby:memory:%s;%s";
@Nullable
private static DerbyEmbeddedDatabaseConfigurer instance;

View File

@@ -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.
@@ -21,7 +21,6 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.util.UUID;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
@@ -77,10 +76,13 @@ public class EmbeddedDatabaseFactory {
private DataSourceFactory dataSourceFactory = new SimpleDriverDataSourceFactory();
@Nullable
private EmbeddedDatabaseConfigurer databaseConfigurer;
@Nullable
private DatabasePopulator databasePopulator;
@Nullable
private DataSource dataSource;
@@ -222,7 +224,9 @@ public class EmbeddedDatabaseFactory {
logger.info(String.format("Shutting down embedded database '%s'", this.databaseName));
}
}
this.databaseConfigurer.shutdown(this.dataSource, this.databaseName);
if (this.databaseConfigurer != null) {
this.databaseConfigurer.shutdown(this.dataSource, this.databaseName);
}
this.dataSource = null;
}
}

View File

@@ -23,6 +23,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.lang.Nullable;
/**
* A subclass of {@link EmbeddedDatabaseFactory} that implements {@link FactoryBean}
@@ -43,6 +44,7 @@ import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory
implements FactoryBean<DataSource>, InitializingBean, DisposableBean {
@Nullable
private DatabasePopulator databaseCleaner;

View File

@@ -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.
@@ -18,6 +18,7 @@ package org.springframework.jdbc.datasource.embedded;
import java.sql.Driver;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -31,6 +32,7 @@ import org.springframework.util.ClassUtils;
*/
final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer {
@Nullable
private static H2EmbeddedDatabaseConfigurer instance;
private final Class<? extends Driver> driverClass;

View File

@@ -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.
@@ -18,6 +18,7 @@ package org.springframework.jdbc.datasource.embedded;
import java.sql.Driver;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -30,6 +31,7 @@ import org.springframework.util.ClassUtils;
*/
final class HsqlEmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer {
@Nullable
private static HsqlEmbeddedDatabaseConfigurer instance;
private final Class<? extends Driver> driverClass;

View File

@@ -35,6 +35,7 @@ import org.springframework.util.Assert;
*/
public class DataSourceInitializer implements InitializingBean, DisposableBean {
@Nullable
private DataSource dataSource;
private DatabasePopulator databasePopulator;

View File

@@ -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.
@@ -20,7 +20,6 @@ import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.core.io.Resource;
@@ -56,6 +55,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
List<Resource> scripts = new ArrayList<>();
@Nullable
private String sqlScriptEncoding;
private String separator = ScriptUtils.DEFAULT_STATEMENT_SEPARATOR;
@@ -155,7 +155,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
* @see #addScript(Resource)
*/
public void setSqlScriptEncoding(@Nullable String sqlScriptEncoding) {
this.sqlScriptEncoding = StringUtils.hasText(sqlScriptEncoding) ? sqlScriptEncoding : null;
this.sqlScriptEncoding = (StringUtils.hasText(sqlScriptEncoding) ? sqlScriptEncoding : null);
}
/**

View File

@@ -40,16 +40,20 @@ import org.springframework.util.Assert;
*/
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
@Nullable
private Map<Object, Object> targetDataSources;
@Nullable
private Object defaultTargetDataSource;
private boolean lenientFallback = true;
private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
@Nullable
private Map<Object, DataSource> resolvedDataSources;
@Nullable
private DataSource resolvedDefaultDataSource;

View File

@@ -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.
@@ -21,6 +21,7 @@ import javax.sql.DataSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -36,6 +37,7 @@ import org.springframework.util.Assert;
*/
public class BeanFactoryDataSourceLookup implements DataSourceLookup, BeanFactoryAware {
@Nullable
private BeanFactory beanFactory;

View File

@@ -35,9 +35,11 @@ import org.springframework.util.Assert;
*/
public class GenericSqlQuery<T> extends SqlQuery<T> {
@Nullable
private RowMapper<T> rowMapper;
@SuppressWarnings("rawtypes")
@Nullable
private Class<? extends RowMapper> rowMapperClass;
@@ -69,7 +71,13 @@ public class GenericSqlQuery<T> extends SqlQuery<T> {
@Override
@SuppressWarnings("unchecked")
protected RowMapper<T> newRowMapper(@Nullable Object[] parameters, @Nullable Map<?, ?> context) {
return (this.rowMapper != null ? this.rowMapper : BeanUtils.instantiateClass(this.rowMapperClass));
if (this.rowMapper != null) {
return this.rowMapper;
}
else {
Assert.state(this.rowMapperClass != null, "No RowMapper set");
return BeanUtils.instantiateClass(this.rowMapperClass);
}
}
}

View File

@@ -102,8 +102,10 @@ public abstract class MappingSqlQueryWithParameters<T> extends SqlQuery<T> {
*/
protected class RowMapperImpl implements RowMapper<T> {
@Nullable
private final Object[] params;
@Nullable
private final Map<?, ?> context;
/**

View File

@@ -72,8 +72,10 @@ public abstract class RdbmsOperation implements InitializingBean {
private boolean returnGeneratedKeys = false;
private String[] generatedKeysColumnNames = null;
@Nullable
private String[] generatedKeysColumnNames;
@Nullable
private String sql;
private final List<SqlParameter> declaredParameters = new LinkedList<>();

View File

@@ -18,7 +18,6 @@ package org.springframework.jdbc.object;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.core.CallableStatementCreator;
@@ -26,6 +25,7 @@ import org.springframework.jdbc.core.CallableStatementCreatorFactory;
import org.springframework.jdbc.core.ParameterMapper;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* RdbmsOperation using a JdbcTemplate and representing a SQL-based
@@ -44,6 +44,7 @@ public abstract class SqlCall extends RdbmsOperation {
* Object enabling us to create CallableStatementCreators
* efficiently, based on this class's declared parameters.
*/
@Nullable
private CallableStatementCreatorFactory callableStatementFactory;
/**
@@ -64,6 +65,7 @@ public abstract class SqlCall extends RdbmsOperation {
* or {? = call get_invoice_count(?)} if isFunction is set to true
* Updated after each parameter is added.
*/
@Nullable
private String callString;
@@ -153,10 +155,10 @@ public abstract class SqlCall extends RdbmsOperation {
this.callString += ")}";
}
if (logger.isDebugEnabled()) {
logger.debug("Compiled stored procedure. Call string is [" + getCallString() + "]");
logger.debug("Compiled stored procedure. Call string is [" + this.callString + "]");
}
this.callableStatementFactory = new CallableStatementCreatorFactory(getCallString(), getDeclaredParameters());
this.callableStatementFactory = new CallableStatementCreatorFactory(this.callString, getDeclaredParameters());
this.callableStatementFactory.setResultSetType(getResultSetType());
this.callableStatementFactory.setUpdatableResults(isUpdatableResults());
@@ -173,6 +175,7 @@ public abstract class SqlCall extends RdbmsOperation {
/**
* Get the call string.
*/
@Nullable
public String getCallString() {
return this.callString;
}
@@ -183,6 +186,7 @@ public abstract class SqlCall extends RdbmsOperation {
* @param inParams parameters. May be {@code null}.
*/
protected CallableStatementCreator newCallableStatementCreator(@Nullable Map<String, ?> inParams) {
Assert.state(this.callableStatementFactory != null, "No CallableStatementFactory available");
return this.callableStatementFactory.newCallableStatementCreator(inParams);
}
@@ -192,6 +196,7 @@ public abstract class SqlCall extends RdbmsOperation {
* @param inParamMapper parametermapper. May not be {@code null}.
*/
protected CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) {
Assert.state(this.callableStatementFactory != null, "No CallableStatementFactory available");
return this.callableStatementFactory.newCallableStatementCreator(inParamMapper);
}

View File

@@ -22,6 +22,7 @@ import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
import org.springframework.jdbc.core.namedparam.ParsedSql;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Operation object representing a SQL-based operation such as a query or update,
@@ -39,9 +40,11 @@ public abstract class SqlOperation extends RdbmsOperation {
* Object enabling us to create PreparedStatementCreators efficiently,
* based on this class's declared parameters.
*/
@Nullable
private PreparedStatementCreatorFactory preparedStatementFactory;
/** Parsed representation of the SQL statement */
@Nullable
private ParsedSql cachedSql;
/** Monitor for locking the cached representation of the parsed SQL statement */
@@ -93,6 +96,7 @@ public abstract class SqlOperation extends RdbmsOperation {
* @param params the parameter array (may be {@code null})
*/
protected final PreparedStatementSetter newPreparedStatementSetter(@Nullable Object[] params) {
Assert.state(this.preparedStatementFactory != null, "No PreparedStatementFactory available");
return this.preparedStatementFactory.newPreparedStatementSetter(params);
}
@@ -102,6 +106,7 @@ public abstract class SqlOperation extends RdbmsOperation {
* @param params the parameter array (may be {@code null})
*/
protected final PreparedStatementCreator newPreparedStatementCreator(@Nullable Object[] params) {
Assert.state(this.preparedStatementFactory != null, "No PreparedStatementFactory available");
return this.preparedStatementFactory.newPreparedStatementCreator(params);
}
@@ -113,6 +118,7 @@ public abstract class SqlOperation extends RdbmsOperation {
* @param params the parameter array (may be {@code null})
*/
protected final PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, @Nullable Object[] params) {
Assert.state(this.preparedStatementFactory != null, "No PreparedStatementFactory available");
return this.preparedStatementFactory.newPreparedStatementCreator(sqlToUse, params);
}

View File

@@ -19,7 +19,6 @@ package org.springframework.jdbc.object;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.core.RowMapper;
@@ -89,6 +88,7 @@ public abstract class UpdatableSqlQuery<T> extends SqlQuery<T> {
*/
protected class RowMapperImpl implements RowMapper<T> {
@Nullable
private final Map<?, ?> context;
public RowMapperImpl(@Nullable Map<?, ?> context) {

View File

@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.lang.Nullable;
/**
* Bean that checks if a database has already started up. To be referenced
@@ -47,8 +48,10 @@ public class DatabaseStartupValidator implements InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private DataSource dataSource;
@Nullable
private String validationQuery;
private int interval = DEFAULT_INTERVAL;

View File

@@ -42,8 +42,10 @@ public abstract class JdbcAccessor implements InitializingBean {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private DataSource dataSource;
@Nullable
private SQLExceptionTranslator exceptionTranslator;
private boolean lazyInit = true;

View File

@@ -74,6 +74,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
/** Error codes used by this translator */
@Nullable
private SQLErrorCodes sqlErrorCodes;
@@ -160,6 +161,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
* Usually determined via a DataSource.
* @see #setDataSource
*/
@Nullable
public SQLErrorCodes getSqlErrorCodes() {
return this.sqlErrorCodes;
}

View File

@@ -35,6 +35,7 @@ import org.springframework.util.StringUtils;
*/
public class SQLErrorCodes {
@Nullable
private String[] databaseProductNames;
private boolean useSqlStateForTranslation = false;
@@ -59,8 +60,10 @@ public class SQLErrorCodes {
private String[] cannotSerializeTransactionCodes = new String[0];
@Nullable
private CustomSQLErrorCodesTranslation[] customTranslations;
@Nullable
private SQLExceptionTranslator customSqlExceptionTranslator;
@@ -86,6 +89,7 @@ public class SQLErrorCodes {
this.databaseProductNames = databaseProductNames;
}
@Nullable
public String[] getDatabaseProductNames() {
return this.databaseProductNames;
}

View File

@@ -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.
@@ -22,6 +22,9 @@ import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import org.springframework.lang.Nullable;
import org.springframework.util.StreamUtils;
/**
* Simple JDBC {@link Blob} adapter that exposes a given byte array or binary stream.
* Optionally used by {@link DefaultLobHandler}.
@@ -31,8 +34,10 @@ import java.sql.SQLException;
*/
class PassThroughBlob implements Blob {
@Nullable
private byte[] content;
@Nullable
private InputStream binaryStream;
private long contentLength;
@@ -56,7 +61,12 @@ class PassThroughBlob implements Blob {
@Override
public InputStream getBinaryStream() throws SQLException {
return (this.content != null ? new ByteArrayInputStream(this.content) : this.binaryStream);
if (this.content != null) {
return new ByteArrayInputStream(this.content);
}
else {
return (this.binaryStream != null ? this.binaryStream : StreamUtils.emptyInput());
}
}

View File

@@ -28,7 +28,9 @@ import java.nio.charset.StandardCharsets;
import java.sql.Clob;
import java.sql.SQLException;
import org.springframework.lang.Nullable;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StreamUtils;
/**
* Simple JDBC {@link Clob} adapter that exposes a given String or character stream.
@@ -39,10 +41,13 @@ import org.springframework.util.FileCopyUtils;
*/
class PassThroughClob implements Clob {
@Nullable
private String content;
@Nullable
private Reader characterStream;
@Nullable
private InputStream asciiStream;
private long contentLength;
@@ -78,7 +83,9 @@ class PassThroughClob implements Clob {
return this.characterStream;
}
else {
return new InputStreamReader(this.asciiStream, StandardCharsets.US_ASCII);
return new InputStreamReader(
(this.asciiStream != null ? this.asciiStream : StreamUtils.emptyInput()),
StandardCharsets.US_ASCII);
}
}
@@ -93,7 +100,7 @@ class PassThroughClob implements Clob {
return new ByteArrayInputStream(tempContent.getBytes(StandardCharsets.US_ASCII));
}
else {
return this.asciiStream;
return (this.asciiStream != null ? this.asciiStream : StreamUtils.emptyInput());
}
}
catch (IOException ex) {

View File

@@ -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.
@@ -20,6 +20,7 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.springframework.jdbc.InvalidResultSetAccessException;
import org.springframework.lang.Nullable;
/**
* The default implementation of Spring's {@link SqlRowSetMetaData} interface, wrapping
@@ -37,6 +38,7 @@ public class ResultSetWrappingSqlRowSetMetaData implements SqlRowSetMetaData {
private final ResultSetMetaData resultSetMetaData;
@Nullable
private String[] columnNames;