diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2016-04-03 01:07:52 +0200 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2016-04-03 01:07:52 +0200 |
commit | 5575b60c30c5a0c308c4ba3a2db93956d8c1746c (patch) | |
tree | 14eb3edc5dfb9f5bd0ce5cb99adac0f51573be94 /spring-jdbc/src | |
parent | da46d30e80e4c59a41cf52055d06faa1dbb7e383 (diff) |
Imported Upstream version 4.1.9
Diffstat (limited to 'spring-jdbc/src')
148 files changed, 1520 insertions, 957 deletions
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java index 043ccf1a..eca9a2fd 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/config/DatabasePopulatorConfigUtils.java @@ -18,6 +18,8 @@ package org.springframework.jdbc.config; import java.util.List; +import org.w3c.dom.Element; + import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.TypedStringValue; @@ -27,7 +29,6 @@ import org.springframework.jdbc.datasource.init.CompositeDatabasePopulator; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; /** * @author Juergen Hoeller diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/config/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/config/package-info.java index 28b676f9..26bc92c9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/config/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/config/package-info.java @@ -1,6 +1,4 @@ - /** * Defines the Spring JDBC configuration namespace. */ package org.springframework.jdbc.config; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java index c888b47e..eec11f6f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java @@ -16,9 +16,9 @@ package org.springframework.jdbc.core; -import java.util.List; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.List; /** * Generic utility methods for working with JDBC batch statements. Mainly for internal use diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java index c65ac159..25f87f66 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -63,7 +63,7 @@ import org.springframework.util.StringUtils; * will have been set to the primitive's default value instead of null. * * <p>Please note that this class is designed to provide convenience rather than high performance. - * For best performance consider using a custom RowMapper. + * For best performance, consider using a custom {@link RowMapper} implementation. * * @author Thomas Risberg * @author Juergen Hoeller diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java index 0c41df7c..15af7524 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java @@ -291,7 +291,7 @@ public interface JdbcOperations { * @return an array of the number of rows affected by each statement * @throws DataAccessException if there is any problem executing the batch */ - int[] batchUpdate(String[] sql) throws DataAccessException; + int[] batchUpdate(String... sql) throws DataAccessException; //------------------------------------------------------------------------- diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index d1cfd94c..6190090e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -111,22 +111,22 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { private boolean ignoreWarnings = true; /** - * If this variable is set to a non-zero value, it will be used for setting the + * If this variable is set to a non-negative value, it will be used for setting the * fetchSize property on statements used for query processing. */ - private int fetchSize = 0; + private int fetchSize = -1; /** - * If this variable is set to a non-zero value, it will be used for setting the + * If this variable is set to a non-negative value, it will be used for setting the * maxRows property on statements used for query processing. */ - private int maxRows = 0; + private int maxRows = -1; /** - * If this variable is set to a non-zero value, it will be used for setting the + * If this variable is set to a non-negative value, it will be used for setting the * queryTimeout property on statements used for query processing. */ - private int queryTimeout = 0; + private int queryTimeout = -1; /** * If this variable is set to true then all results checking will be bypassed for any @@ -224,7 +224,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { * large result sets: Setting this higher than the default value will increase * processing speed at the cost of memory consumption; setting this lower can * avoid transferring row data that will never be read by the application. - * <p>Default is 0, indicating to use the JDBC driver's default. + * <p>Default is -1, indicating to use the JDBC driver's default + * (i.e. to not pass a specific fetch size setting on the driver). * @see java.sql.Statement#setFetchSize */ public void setFetchSize(int fetchSize) { @@ -244,7 +245,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { * the entire result set in the database or in the JDBC driver if we're * never interested in the entire result in the first place (for example, * when performing searches that might return a large number of matches). - * <p>Default is 0, indicating to use the JDBC driver's default. + * <p>Default is -1, indicating to use the JDBC driver's default + * (i.e. to not pass a specific max rows setting on the driver). * @see java.sql.Statement#setMaxRows */ public void setMaxRows(int maxRows) { @@ -260,7 +262,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { /** * Set the query timeout for statements that this JdbcTemplate executes. - * <p>Default is 0, indicating to use the JDBC driver's default. + * <p>Default is -1, indicating to use the JDBC driver's default + * (i.e. to not pass a specific query timeout setting on the driver). * <p>Note: Any timeout specified here will be overridden by the remaining * transaction timeout when executing within a transaction that has a * timeout specified at the transaction level. @@ -547,10 +550,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } @Override - public int[] batchUpdate(final String[] sql) throws DataAccessException { - + public int[] batchUpdate(final String... sql) throws DataAccessException { Assert.notEmpty(sql, "SQL array must not be empty"); - if (logger.isDebugEnabled()) { logger.debug("Executing SQL batch update of " + sql.length + " statements"); } @@ -561,9 +562,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { @Override public int[] doInStatement(Statement stmt) throws SQLException, DataAccessException { - int[] rowsAffected = new int[sql.length]; - if (JdbcUtils.supportsBatchUpdates(stmt.getConnection())) { for (String sqlStmt : sql) { this.currSql = appendSql(this.currSql, sqlStmt); @@ -608,6 +607,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { return this.currSql; } } + return execute(new BatchUpdateStatementCallback()); } @@ -1389,11 +1389,11 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { */ protected void applyStatementSettings(Statement stmt) throws SQLException { int fetchSize = getFetchSize(); - if (fetchSize > 0) { + if (fetchSize >= 0) { stmt.setFetchSize(fetchSize); } int maxRows = getMaxRows(); - if (maxRows > 0) { + if (maxRows >= 0) { stmt.setMaxRows(maxRows); } DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout()); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java index 1625c4c1..8ef34479 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Set; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.Assert; @@ -228,18 +227,11 @@ public class PreparedStatementCreatorFactory { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps; if (generatedKeysColumnNames != null || returnGeneratedKeys) { - try { - if (generatedKeysColumnNames != null) { - ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames); - } - else { - ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS); - } + if (generatedKeysColumnNames != null) { + ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames); } - catch (AbstractMethodError err) { - throw new InvalidDataAccessResourceUsageException( - "Your JDBC driver is not compliant with JDBC 3.0 - " + - "it does not support retrieval of auto-generated keys", err); + else { + ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS); } } else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java index 376810bf..32119248 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java @@ -16,12 +16,12 @@ package org.springframework.jdbc.core; -import org.springframework.jdbc.support.JdbcUtils; - import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; +import org.springframework.jdbc.support.JdbcUtils; + /** * Implementation of RowCallbackHandler. Convenient superclass for callback handlers. * An instance can only be used once. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java index 17493853..fb489784 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -185,4 +185,17 @@ public class SingleColumnRowMapper<T> implements RowMapper<T> { } } + + /** + * Static factory method to create a new ParameterizedSingleColumnRowMapper + * (with the required type specified only once). + * @param requiredType the type that each result object is expected to match + * @since 4.1 + */ + public static <T> SingleColumnRowMapper<T> newInstance(Class<T> requiredType) { + SingleColumnRowMapper<T> newInstance = new SingleColumnRowMapper<T>(); + newInstance.setRequiredType(requiredType); + return newInstance; + } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlParameter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlParameter.java index 99397e37..82a82962 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlParameter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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,7 +43,6 @@ public class SqlParameter { /** Used for types that are user-named like: STRUCT, DISTINCT, JAVA_OBJECT, named array types */ private String typeName; - /** The scale to apply in case of a NUMERIC or DECIMAL type, if any */ private Integer scale; @@ -126,7 +125,7 @@ public class SqlParameter { /** - * Return the name of the parameter. + * Return the name of the parameter, or {@code null} if anonymous. */ public String getName() { return this.name; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java index 7a69f2c4..f0347bb5 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java @@ -25,6 +25,7 @@ import javax.sql.rowset.RowSetProvider; import org.springframework.core.JdkVersion; import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet; +import org.springframework.lang.UsesJava7; import org.springframework.util.ClassUtils; /** @@ -109,6 +110,7 @@ public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet /** * Inner class to avoid a hard dependency on JDBC 4.1 RowSetProvider class. */ + @UsesJava7 private static class StandardCachedRowSetFactory implements CachedRowSetFactory { private final RowSetFactory rowSetFactory; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java index 1c3ada01..9d1fdd7e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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,6 +16,7 @@ package org.springframework.jdbc.core; +import java.io.StringReader; import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; @@ -24,6 +25,7 @@ import java.sql.Clob; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.sql.Types; import java.util.Arrays; import java.util.Calendar; @@ -87,10 +89,8 @@ public abstract class StatementCreatorUtils { private static final Map<Class<?>, Integer> javaTypeToSqlTypeMap = new HashMap<Class<?>, Integer>(32); static { - /* JDBC 3.0 only - not compatible with e.g. MySQL at present - javaTypeToSqlTypeMap.put(boolean.class, new Integer(Types.BOOLEAN)); - javaTypeToSqlTypeMap.put(Boolean.class, new Integer(Types.BOOLEAN)); - */ + javaTypeToSqlTypeMap.put(boolean.class, Types.BOOLEAN); + javaTypeToSqlTypeMap.put(Boolean.class, Types.BOOLEAN); javaTypeToSqlTypeMap.put(byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(Byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(short.class, Types.SMALLINT); @@ -241,7 +241,7 @@ public abstract class StatementCreatorUtils { * respecting database-specific peculiarities. */ private static void setNull(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException { - if (sqlType == SqlTypeValue.TYPE_UNKNOWN) { + if (sqlType == SqlTypeValue.TYPE_UNKNOWN || sqlType == Types.OTHER) { boolean useSetObject = false; Integer sqlTypeToUse = null; DatabaseMetaData dbmd = null; @@ -282,7 +282,8 @@ public abstract class StatementCreatorUtils { } String databaseProductName = dbmd.getDatabaseProductName(); if (databaseProductName.startsWith("Informix") || - jdbcDriverName.startsWith("Microsoft SQL Server")) { + (jdbcDriverName.startsWith("Microsoft") && jdbcDriverName.contains("SQL Server"))) { + // "Microsoft SQL Server JDBC Driver 3.0" versus "Microsoft JDBC Driver 4.0 for SQL Server" useSetObject = true; } else if (databaseProductName.startsWith("DB2") || @@ -320,10 +321,34 @@ public abstract class StatementCreatorUtils { else if (inValue instanceof SqlValue) { ((SqlValue) inValue).setValue(ps, paramIndex); } - else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR || - (sqlType == Types.CLOB && isStringValue(inValue.getClass()))) { + else if (sqlType == Types.VARCHAR || sqlType == Types.NVARCHAR || + sqlType == Types.LONGVARCHAR || sqlType == Types.LONGNVARCHAR) { ps.setString(paramIndex, inValue.toString()); } + else if ((sqlType == Types.CLOB || sqlType == Types.NCLOB) && isStringValue(inValue.getClass())) { + String strVal = inValue.toString(); + if (strVal.length() > 4000) { + // Necessary for older Oracle drivers, in particular when running against an Oracle 10 database. + // Should also work fine against other drivers/databases since it uses standard JDBC 4.0 API. + try { + if (sqlType == Types.NCLOB) { + ps.setNClob(paramIndex, new StringReader(strVal), strVal.length()); + } + else { + ps.setClob(paramIndex, new StringReader(strVal), strVal.length()); + } + return; + } + catch (AbstractMethodError err) { + logger.debug("JDBC driver does not implement JDBC 4.0 'setClob(int, Reader, long)' method", err); + } + catch (SQLFeatureNotSupportedException ex) { + logger.debug("JDBC driver does not support JDBC 4.0 'setClob(int, Reader, long)' method", ex); + } + } + // Fallback: regular setString binding + ps.setString(paramIndex, strVal); + } else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) { if (inValue instanceof BigDecimal) { ps.setBigDecimal(paramIndex, (BigDecimal) inValue); @@ -386,7 +411,8 @@ public abstract class StatementCreatorUtils { ps.setObject(paramIndex, inValue, Types.TIMESTAMP); } } - else if (sqlType == SqlTypeValue.TYPE_UNKNOWN) { + else if (sqlType == SqlTypeValue.TYPE_UNKNOWN || (sqlType == Types.OTHER && + "Oracle".equals(ps.getConnection().getMetaData().getDatabaseProductName()))) { if (isStringValue(inValue.getClass())) { ps.setString(paramIndex, inValue.toString()); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java index 70daa10b..45b496aa 100755 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -280,88 +280,94 @@ public class CallMetaDataContext { * Reconcile the provided parameters with available metadata and add new ones where appropriate. */ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) { - final List<SqlParameter> declaredReturnParameters = new ArrayList<SqlParameter>(); - final Map<String, SqlParameter> declaredParameters = new LinkedHashMap<String, SqlParameter>(); + final List<SqlParameter> declaredReturnParams = new ArrayList<SqlParameter>(); + final Map<String, SqlParameter> declaredParams = new LinkedHashMap<String, SqlParameter>(); boolean returnDeclared = false; - List<String> outParameterNames = new ArrayList<String>(); - List<String> metaDataParameterNames = new ArrayList<String>(); + List<String> outParamNames = new ArrayList<String>(); + List<String> metaDataParamNames = new ArrayList<String>(); // Get the names of the meta data parameters for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) { - metaDataParameterNames.add(meta.getParameterName().toLowerCase()); + metaDataParamNames.add(meta.getParameterName().toLowerCase()); } } // Separate implicit return parameters from explicit parameters... - for (SqlParameter parameter : parameters) { - if (parameter.isResultsParameter()) { - declaredReturnParameters.add(parameter); + for (SqlParameter param : parameters) { + if (param.isResultsParameter()) { + declaredReturnParams.add(param); } else { - String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameter.getName()).toLowerCase(); - declaredParameters.put(parameterNameToMatch, parameter); - if (parameter instanceof SqlOutParameter) { - outParameterNames.add(parameter.getName()); - if (isFunction() && !metaDataParameterNames.contains(parameterNameToMatch)) { + String paramName = param.getName(); + if (paramName == null) { + throw new IllegalArgumentException("Anonymous parameters not supported for calls - " + + "please specify a name for the parameter of SQL type " + param.getSqlType()); + } + String paramNameToMatch = this.metaDataProvider.parameterNameToUse(paramName).toLowerCase(); + declaredParams.put(paramNameToMatch, param); + if (param instanceof SqlOutParameter) { + outParamNames.add(paramName); + if (isFunction() && !metaDataParamNames.contains(paramNameToMatch)) { if (!returnDeclared) { if (logger.isDebugEnabled()) { - logger.debug("Using declared out parameter '" + parameter.getName() + "' for function return value"); + logger.debug("Using declared out parameter '" + paramName + + "' for function return value"); } - setFunctionReturnName(parameter.getName()); + setFunctionReturnName(paramName); returnDeclared = true; } } } } } - setOutParameterNames(outParameterNames); + setOutParameterNames(outParamNames); - List<SqlParameter> workParameters = new ArrayList<SqlParameter>(); - workParameters.addAll(declaredReturnParameters); + List<SqlParameter> workParams = new ArrayList<SqlParameter>(); + workParams.addAll(declaredReturnParams); if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) { - workParameters.addAll(declaredParameters.values()); - return workParameters; + workParams.addAll(declaredParams.values()); + return workParams; } Map<String, String> limitedInParamNamesMap = new HashMap<String, String>(this.limitedInParameterNames.size()); - for (String limitedParameterName : this.limitedInParameterNames) { + for (String limitedParamName : this.limitedInParameterNames) { limitedInParamNamesMap.put( - this.metaDataProvider.parameterNameToUse(limitedParameterName).toLowerCase(), limitedParameterName); + this.metaDataProvider.parameterNameToUse(limitedParamName).toLowerCase(), limitedParamName); } for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { - String parNameToCheck = null; + String paramNameToCheck = null; if (meta.getParameterName() != null) { - parNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase(); + paramNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase(); } - String parNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName()); - if (declaredParameters.containsKey(parNameToCheck) || + String paramNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName()); + if (declaredParams.containsKey(paramNameToCheck) || (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) { - SqlParameter parameter; + SqlParameter param; if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { - parameter = declaredParameters.get(getFunctionReturnName()); - if (parameter == null && getOutParameterNames().size() > 0) { - parameter = declaredParameters.get(getOutParameterNames().get(0).toLowerCase()); + param = declaredParams.get(getFunctionReturnName()); + if (param == null && getOutParameterNames().size() > 0) { + param = declaredParams.get(getOutParameterNames().get(0).toLowerCase()); } - if (parameter == null) { + if (param == null) { throw new InvalidDataAccessApiUsageException( "Unable to locate declared parameter for function return value - " + - " add a SqlOutParameter with name \"" + getFunctionReturnName() +"\""); + " add a SqlOutParameter with name '" + getFunctionReturnName() + "'"); } else { - setFunctionReturnName(parameter.getName()); + setFunctionReturnName(param.getName()); } } else { - parameter = declaredParameters.get(parNameToCheck); + param = declaredParams.get(paramNameToCheck); } - if (parameter != null) { - workParameters.add(parameter); + if (param != null) { + workParams.add(param); if (logger.isDebugEnabled()) { - logger.debug("Using declared parameter for: " + - (parNameToUse == null ? getFunctionReturnName() : parNameToUse)); + logger.debug("Using declared parameter for '" + + (paramNameToUse != null ? paramNameToUse : getFunctionReturnName()) + "'"); } } } @@ -370,49 +376,49 @@ public class CallMetaDataContext { if (!isFunction() && !isReturnValueRequired() && this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) { if (logger.isDebugEnabled()) { - logger.debug("Bypassing metadata return parameter for: " + meta.getParameterName()); + logger.debug("Bypassing metadata return parameter for '" + meta.getParameterName() + "'"); } } else { String returnNameToUse =(StringUtils.hasLength(meta.getParameterName()) ? - parNameToUse : getFunctionReturnName()); - workParameters.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta)); + paramNameToUse : getFunctionReturnName()); + workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta)); if (isFunction()) { setFunctionReturnName(returnNameToUse); - outParameterNames.add(returnNameToUse); + outParamNames.add(returnNameToUse); } if (logger.isDebugEnabled()) { - logger.debug("Added metadata return parameter for: " + returnNameToUse); + logger.debug("Added metadata return parameter for '" + returnNameToUse + "'"); } } } else { if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) { - workParameters.add(this.metaDataProvider.createDefaultOutParameter(parNameToUse, meta)); - outParameterNames.add(parNameToUse); + workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta)); + outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { - logger.debug("Added metadata out parameter for: " + parNameToUse); + logger.debug("Added metadata out parameter for '" + paramNameToUse + "'"); } } else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) { - workParameters.add(this.metaDataProvider.createDefaultInOutParameter(parNameToUse, meta)); - outParameterNames.add(parNameToUse); + workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta)); + outParamNames.add(paramNameToUse); if (logger.isDebugEnabled()) { - logger.debug("Added metadata in out parameter for: " + parNameToUse); + logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'"); } } else { if (this.limitedInParameterNames.isEmpty() || - limitedInParamNamesMap.containsKey(parNameToUse.toLowerCase())) { - workParameters.add(this.metaDataProvider.createDefaultInParameter(parNameToUse, meta)); + limitedInParamNamesMap.containsKey(paramNameToUse.toLowerCase())) { + workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta)); if (logger.isDebugEnabled()) { - logger.debug("Added metadata in parameter for: " + parNameToUse); + logger.debug("Added metadata in parameter for '" + paramNameToUse + "'"); } } else { if (logger.isDebugEnabled()) { logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() + - " skipped parameter for: " + parNameToUse); + " skipped parameter for '" + paramNameToUse + "'"); } } } @@ -420,7 +426,7 @@ public class CallMetaDataContext { } } - return workParameters; + return workParams; } /** diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java index 62d56910..dc4b90f1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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.DatabaseMetaData; import java.sql.SQLException; import java.util.Arrays; import java.util.List; - import javax.sql.DataSource; import org.apache.commons.logging.Log; @@ -32,16 +31,14 @@ import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.MetaDataAccessException; /** - * Factory used to create a {@link CallMetaDataProvider} implementation based on the type of databse being used. + * Factory used to create a {@link CallMetaDataProvider} implementation + * based on the type of database being used. * * @author Thomas Risberg * @since 2.5 */ public class CallMetaDataProviderFactory { - /** Logger */ - private static final Log logger = LogFactory.getLog(CallMetaDataProviderFactory.class); - /** List of supported database products for procedure calls */ public static final List<String> supportedDatabaseProductsForProcedures = Arrays.asList( "Apache Derby", @@ -52,6 +49,7 @@ public class CallMetaDataProviderFactory { "PostgreSQL", "Sybase" ); + /** List of supported database products for function calls */ public static final List<String> supportedDatabaseProductsForFunctions = Arrays.asList( "MySQL", @@ -60,6 +58,9 @@ public class CallMetaDataProviderFactory { "PostgreSQL" ); + private static final Log logger = LogFactory.getLog(CallMetaDataProviderFactory.class); + + /** * Create a CallMetaDataProvider based on the database metadata * @param dataSource used to retrieve metadata @@ -125,17 +126,16 @@ public class CallMetaDataProviderFactory { } provider.initializeWithMetaData(databaseMetaData); if (accessProcedureColumnMetaData) { - provider.initializeWithProcedureColumnMetaData( - databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getProcedureName()); + provider.initializeWithProcedureColumnMetaData(databaseMetaData, + context.getCatalogName(), context.getSchemaName(), context.getProcedureName()); } return provider; } }); } catch (MetaDataAccessException ex) { - throw new DataAccessResourceFailureException("Error retreiving database metadata", ex); + throw new DataAccessResourceFailureException("Error retrieving database metadata", ex); } - } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java index 24e66c42..ebc4ec87 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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,7 +70,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { Arrays.asList("Apache Derby", "HSQL Database Engine"); /** Collection of TableParameterMetaData objects */ - private List<TableParameterMetaData> insertParameterMetaData = new ArrayList<TableParameterMetaData>(); + private List<TableParameterMetaData> tableParameterMetaData = new ArrayList<TableParameterMetaData>(); /** NativeJdbcExtractor that can be used to retrieve the native connection */ private NativeJdbcExtractor nativeJdbcExtractor; @@ -109,7 +109,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { @Override public List<TableParameterMetaData> getTableParameterMetaData() { - return this.insertParameterMetaData; + return this.tableParameterMetaData; } @Override @@ -376,17 +376,14 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } try { tableColumns = databaseMetaData.getColumns( - metaDataCatalogName, - metaDataSchemaName, - metaDataTableName, - null); + metaDataCatalogName, metaDataSchemaName, metaDataTableName, null); while (tableColumns.next()) { String columnName = tableColumns.getString("COLUMN_NAME"); int dataType = tableColumns.getInt("DATA_TYPE"); if (dataType == Types.DECIMAL) { String typeName = tableColumns.getString("TYPE_NAME"); int decimalDigits = tableColumns.getInt("DECIMAL_DIGITS"); - // override a DECIMAL data type for no-decimal numerics + // Override a DECIMAL data type for no-decimal numerics // (this is for better Oracle support where there have been issues // using DECIMAL for certain inserts (see SPR-6912)) if ("NUMBER".equals(typeName) && decimalDigits == 0) { @@ -400,18 +397,11 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } } boolean nullable = tableColumns.getBoolean("NULLABLE"); - TableParameterMetaData meta = new TableParameterMetaData( - columnName, - dataType, - nullable - ); - this.insertParameterMetaData.add(meta); + TableParameterMetaData meta = new TableParameterMetaData(columnName, dataType, nullable); + this.tableParameterMetaData.add(meta); if (logger.isDebugEnabled()) { - logger.debug("Retrieved metadata: " - + meta.getParameterName() + - " " + meta.getSqlType() + - " " + meta.isNullable() - ); + logger.debug("Retrieved metadata: " + meta.getParameterName() + + " " + meta.getSqlType() + " " + meta.isNullable()); } } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java index 62040f12..33c25c20 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.java @@ -16,14 +16,14 @@ package org.springframework.jdbc.core.metadata; -import org.springframework.jdbc.core.SqlParameter; -import org.springframework.jdbc.core.SqlOutParameter; -import org.springframework.jdbc.core.ColumnMapRowMapper; - import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.Types; +import org.springframework.jdbc.core.ColumnMapRowMapper; +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. * This class is intended for internal use by the Simple JDBC classes. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java index f3391db2..63ea39ec 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -17,8 +17,8 @@ package org.springframework.jdbc.core.metadata; import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -39,6 +39,7 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; * and execution of operations on a database table. * * @author Thomas Risberg + * @author Juergen Hoeller * @since 2.5 */ public class TableMetaDataContext { @@ -201,7 +202,8 @@ public class TableMetaDataContext { * @param generatedKeyNames name of generated keys */ public void processMetaData(DataSource dataSource, List<String> declaredColumns, String[] generatedKeyNames) { - this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor); + this.metaDataProvider = + TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor); this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames); } @@ -217,7 +219,7 @@ public class TableMetaDataContext { if (declaredColumns.size() > 0) { return new ArrayList<String>(declaredColumns); } - Set<String> keys = new HashSet<String>(generatedKeyNames.length); + Set<String> keys = new LinkedHashSet<String>(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } @@ -274,9 +276,9 @@ public class TableMetaDataContext { * Match the provided column names and values with the list of columns used. * @param inParameters the parameter names and values */ - public List<Object> matchInParameterValuesWithInsertColumns(Map<String, Object> inParameters) { + public List<Object> matchInParameterValuesWithInsertColumns(Map<String, ?> inParameters) { List<Object> values = new ArrayList<Object>(); - Map<String, Object> source = new HashMap<String, Object>(); + Map<String, Object> source = new LinkedHashMap<String, Object>(inParameters.size()); for (String key : inParameters.keySet()) { source.put(key.toLowerCase(), inParameters.get(key)); } @@ -292,20 +294,20 @@ public class TableMetaDataContext { * @return the insert string to be used */ public String createInsertString(String... generatedKeyNames) { - HashSet<String> keys = new HashSet<String>(generatedKeyNames.length); + Set<String> keys = new LinkedHashSet<String>(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } StringBuilder insertStatement = new StringBuilder(); insertStatement.append("INSERT INTO "); - if (this.getSchemaName() != null) { - insertStatement.append(this.getSchemaName()); + if (getSchemaName() != null) { + insertStatement.append(getSchemaName()); insertStatement.append("."); } - insertStatement.append(this.getTableName()); + insertStatement.append(getTableName()); insertStatement.append(" ("); int columnCount = 0; - for (String columnName : this.getTableColumns()) { + for (String columnName : getTableColumns()) { if (!keys.contains(columnName.toUpperCase())) { columnCount++; if (columnCount > 1) { @@ -318,11 +320,11 @@ public class TableMetaDataContext { if (columnCount < 1) { if (this.generatedKeyColumnsUsed) { logger.info("Unable to locate non-key columns for table '" + - this.getTableName() + "' so an empty insert statement is generated"); + getTableName() + "' so an empty insert statement is generated"); } else { throw new InvalidDataAccessApiUsageException("Unable to locate columns for table '" + - this.getTableName() + "' so an insert statement can't be generated"); + getTableName() + "' so an insert statement can't be generated"); } } for (int i = 0; i < columnCount; i++) { @@ -340,14 +342,15 @@ public class TableMetaDataContext { * @return the array of types to be used */ public int[] createInsertTypes() { - int[] types = new int[this.getTableColumns().size()]; + int[] types = new int[getTableColumns().size()]; List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData(); - Map<String, TableParameterMetaData> parameterMap = new HashMap<String, TableParameterMetaData>(parameters.size()); + Map<String, TableParameterMetaData> parameterMap = + new LinkedHashMap<String, TableParameterMetaData>(parameters.size()); for (TableParameterMetaData tpmd : parameters) { parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd); } int typeIndx = 0; - for (String column : this.getTableColumns()) { + for (String column : getTableColumns()) { if (column == null) { types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java index 36bc50ed..f2e8cc52 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -30,7 +30,8 @@ import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** - * Factory used to create a {@link TableMetaDataProvider} implementation based on the type of databse being used. + * Factory used to create a {@link TableMetaDataProvider} implementation + * based on the type of database being used. * * @author Thomas Risberg * @since 2.5 diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/package-info.java index 27f00c43..7ad1eaee 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/package-info.java @@ -1,8 +1,4 @@ - /** - * * Context metadata abstraction for the configuration and execution of a stored procedure call. - * */ package org.springframework.jdbc.core.metadata; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSource.java index 1212c42c..af40df75 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -17,7 +17,7 @@ package org.springframework.jdbc.core.namedparam; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.jdbc.core.SqlParameterValue; @@ -29,8 +29,8 @@ import org.springframework.util.Assert; * <p>This class is intended for passing in a simple Map of parameter values * to the methods of the {@link NamedParameterJdbcTemplate} class. * - * <p>The {@code addValue} methods on this class will make adding several - * values easier. The methods return a reference to the {@link MapSqlParameterSource} + * <p>The {@code addValue} methods on this class will make adding several values + * easier. The methods return a reference to the {@link MapSqlParameterSource} * itself, so you can chain several method calls together within a single statement. * * @author Thomas Risberg @@ -43,7 +43,7 @@ import org.springframework.util.Assert; */ public class MapSqlParameterSource extends AbstractSqlParameterSource { - private final Map<String, Object> values = new HashMap<String, Object>(); + private final Map<String, Object> values = new LinkedHashMap<String, Object>(); /** diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java index fd711b43..5fd0a6a2 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java @@ -19,9 +19,9 @@ package org.springframework.jdbc.core.namedparam; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.BatchUpdateUtils; import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.BatchPreparedStatementSetter; /** * Generic utility methods for working with JDBC batch statements using named parameters. Mainly for internal use diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java index e9f3f04e..89ebde23 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.java @@ -18,6 +18,7 @@ package org.springframework.jdbc.core.namedparam; import java.util.HashMap; import java.util.Map; + import org.springframework.jdbc.core.SqlParameterValue; /** diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/package-info.java index 2292bf39..50928e43 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/package-info.java @@ -1,5 +1,4 @@ /** - * * JdbcTemplate variant with named parameter support. * * <p>NamedParameterJdbcTemplate is a wrapper around JdbcTemplate that adds @@ -10,7 +9,5 @@ * <P>If you need the full power of Spring JDBC for less common operations, use * the {@code getJdbcOperations()} method of NamedParameterJdbcTemplate and * work with the returned classic template, or use a JdbcTemplate instance directly. - * */ package org.springframework.jdbc.core.namedparam; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/package-info.java index 332debfb..2a769e03 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/package-info.java @@ -1,9 +1,5 @@ - /** - * * Provides the core JDBC framework, based on JdbcTemplate * and its associated callback interfaces and helper objects. - * */ package org.springframework.jdbc.core; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java index 56cf2084..591b782c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -67,7 +67,7 @@ public abstract class AbstractJdbcCall { * Has this operation been compiled? Compilation means at least checking * that a DataSource or JdbcTemplate has been provided. */ - private boolean compiled = false; + private volatile boolean compiled = false; /** The generated string used for call statement */ private String callString; @@ -314,7 +314,7 @@ public abstract class AbstractJdbcCall { /** * Is this operation "compiled"? - * @return whether this operation is compiled, and ready to use. + * @return whether this operation is compiled and ready to use */ public boolean isCompiled() { return this.compiled; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java index 0f9b8fb3..3af9f463 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -80,7 +80,7 @@ public abstract class AbstractJdbcInsert { * Has this operation been compiled? Compilation means at least checking * that a DataSource or JdbcTemplate has been provided. */ - private boolean compiled = false; + private volatile boolean compiled = false; /** The generated string used for insert statement */ private String insertString; @@ -296,7 +296,7 @@ public abstract class AbstractJdbcInsert { /** * Is this operation "compiled"? - * @return whether this operation is compiled, and ready to use. + * @return whether this operation is compiled and ready to use */ public boolean isCompiled() { return this.compiled; @@ -335,7 +335,7 @@ public abstract class AbstractJdbcInsert { * @param args Map with parameter names and values to be used in insert * @return the number of rows affected */ - protected int doExecute(Map<String, Object> args) { + protected int doExecute(Map<String, ?> args) { checkCompiled(); List<Object> values = matchInParameterValuesWithInsertColumns(args); return executeInsertInternal(values); @@ -355,7 +355,7 @@ public abstract class AbstractJdbcInsert { /** * Delegate method to execute the insert. */ - private int executeInsertInternal(List<Object> values) { + private int executeInsertInternal(List<?> values) { if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for insert " + getInsertString() + " with: " + values); } @@ -368,7 +368,7 @@ public abstract class AbstractJdbcInsert { * @param args Map with parameter names and values to be used in insert * @return the key generated by the insert */ - protected Number doExecuteAndReturnKey(Map<String, Object> args) { + protected Number doExecuteAndReturnKey(Map<String, ?> args) { checkCompiled(); List<Object> values = matchInParameterValuesWithInsertColumns(args); return executeInsertAndReturnKeyInternal(values); @@ -392,7 +392,7 @@ public abstract class AbstractJdbcInsert { * @param args Map with parameter names and values to be used in insert * @return the KeyHolder containing keys generated by the insert */ - protected KeyHolder doExecuteAndReturnKeyHolder(Map<String, Object> args) { + protected KeyHolder doExecuteAndReturnKeyHolder(Map<String, ?> args) { checkCompiled(); List<Object> values = matchInParameterValuesWithInsertColumns(args); return executeInsertAndReturnKeyHolderInternal(values); @@ -413,7 +413,7 @@ public abstract class AbstractJdbcInsert { /** * Delegate method to execute the insert, generating a single key. */ - private Number executeInsertAndReturnKeyInternal(final List<Object> values) { + private Number executeInsertAndReturnKeyInternal(final List<?> values) { KeyHolder kh = executeInsertAndReturnKeyHolderInternal(values); if (kh != null && kh.getKey() != null) { return kh.getKey(); @@ -427,7 +427,7 @@ public abstract class AbstractJdbcInsert { /** * Delegate method to execute the insert, generating any number of keys. */ - private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<Object> values) { + private KeyHolder executeInsertAndReturnKeyHolderInternal(final List<?> values) { if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values); } @@ -542,14 +542,11 @@ public abstract class AbstractJdbcInsert { * @param batch array of Maps with parameter names and values to be used in batch insert * @return array of number of rows affected */ - @SuppressWarnings({"unchecked", "rawtypes"}) - protected int[] doExecuteBatch(Map<String, Object>[] batch) { + protected int[] doExecuteBatch(Map<String, ?>... batch) { checkCompiled(); - List[] batchValues = new ArrayList[batch.length]; - int i = 0; - for (Map<String, Object> args : batch) { - List<Object> values = matchInParameterValuesWithInsertColumns(args); - batchValues[i++] = values; + List<List<Object>> batchValues = new ArrayList<List<Object>>(batch.length); + for (Map<String, ?> args : batch) { + batchValues.add(matchInParameterValuesWithInsertColumns(args)); } return executeBatchInternal(batchValues); } @@ -559,14 +556,11 @@ public abstract class AbstractJdbcInsert { * @param batch array of SqlParameterSource with parameter names and values to be used in insert * @return array of number of rows affected */ - @SuppressWarnings({"unchecked", "rawtypes"}) - protected int[] doExecuteBatch(SqlParameterSource[] batch) { + protected int[] doExecuteBatch(SqlParameterSource... batch) { checkCompiled(); - List[] batchValues = new ArrayList[batch.length]; - int i = 0; + List<List<Object>> batchValues = new ArrayList<List<Object>>(batch.length); for (SqlParameterSource parameterSource : batch) { - List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource); - batchValues[i++] = values; + batchValues.add(matchInParameterValuesWithInsertColumns(parameterSource)); } return executeBatchInternal(batchValues); } @@ -574,20 +568,19 @@ public abstract class AbstractJdbcInsert { /** * Delegate method to execute the batch insert. */ - private int[] executeBatchInternal(final List<Object>[] batchValues) { + private int[] executeBatchInternal(final List<List<Object>> batchValues) { if (logger.isDebugEnabled()) { - logger.debug("Executing statement " + getInsertString() + " with batch of size: " + batchValues.length); + logger.debug("Executing statement " + getInsertString() + " with batch of size: " + batchValues.size()); } return getJdbcTemplate().batchUpdate(getInsertString(), new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { - List<Object> values = batchValues[i]; - setParameterValues(ps, values, getInsertTypes()); + setParameterValues(ps, batchValues.get(i), getInsertTypes()); } @Override public int getBatchSize() { - return batchValues.length; + return batchValues.size(); } }); } @@ -597,7 +590,7 @@ public abstract class AbstractJdbcInsert { * @param preparedStatement the PreparedStatement * @param values the values to be set */ - private void setParameterValues(PreparedStatement preparedStatement, List<Object> values, int[] columnTypes) + private void setParameterValues(PreparedStatement preparedStatement, List<?> values, int... columnTypes) throws SQLException { int colIndex = 0; @@ -628,7 +621,7 @@ public abstract class AbstractJdbcInsert { * @param args the parameter values provided in a Map * @return Map with parameter names and values */ - protected List<Object> matchInParameterValuesWithInsertColumns(Map<String, Object> args) { + protected List<Object> matchInParameterValuesWithInsertColumns(Map<String, ?> args) { return this.tableMetaDataContext.matchInParameterValuesWithInsertColumns(args); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapper.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapper.java index 5c6e2fe7..1019c929 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapper.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapper.java @@ -43,13 +43,17 @@ import org.springframework.jdbc.core.BeanPropertyRowMapper; * try using column aliases in the SQL statement like "select fname as first_name from customer". * * <p>Please note that this class is designed to provide convenience rather than high performance. - * For best performance consider using a custom RowMapper. + * For best performance, consider using a custom {@link org.springframework.jdbc.core.RowMapper} + * implementation. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 * @see ParameterizedRowMapper + * @deprecated along with {@link SimpleJdbcTemplate}, in favor of the regular + * {@link org.springframework.jdbc.core.BeanPropertyRowMapper} */ +@Deprecated public class ParameterizedBeanPropertyRowMapper<T> extends BeanPropertyRowMapper<T> implements ParameterizedRowMapper<T> { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedRowMapper.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedRowMapper.java index b6c75187..e57349af 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedRowMapper.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedRowMapper.java @@ -27,7 +27,10 @@ import org.springframework.jdbc.core.RowMapper; * @author Juergen Hoeller * @since 2.0 * @see org.springframework.jdbc.core.simple.SimpleJdbcOperations + * @deprecated along with {@link SimpleJdbcTemplate}, in favor of the regular + * {@link RowMapper} */ +@Deprecated public interface ParameterizedRowMapper<T> extends RowMapper<T> { } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedSingleColumnRowMapper.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedSingleColumnRowMapper.java index fa82b651..252e0093 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedSingleColumnRowMapper.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedSingleColumnRowMapper.java @@ -32,7 +32,10 @@ import org.springframework.jdbc.core.SingleColumnRowMapper; * * @author Juergen Hoeller * @since 2.5.2 + * @deprecated along with {@link SimpleJdbcTemplate}, in favor of the regular + * {@link org.springframework.jdbc.core.SingleColumnRowMapper} */ +@Deprecated public class ParameterizedSingleColumnRowMapper<T> extends SingleColumnRowMapper<T> implements ParameterizedRowMapper<T> { @@ -42,9 +45,9 @@ public class ParameterizedSingleColumnRowMapper<T> extends SingleColumnRowMapper * @param requiredType the type that each result object is expected to match */ public static <T> ParameterizedSingleColumnRowMapper<T> newInstance(Class<T> requiredType) { - ParameterizedSingleColumnRowMapper<T> rm = new ParameterizedSingleColumnRowMapper<T>(); - rm.setRequiredType(requiredType); - return rm; + ParameterizedSingleColumnRowMapper<T> newInstance = new ParameterizedSingleColumnRowMapper<T>(); + newInstance.setRequiredType(requiredType); + return newInstance; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCall.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCall.java index df58d5d0..f4d37dd0 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCall.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCall.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -39,18 +39,19 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource; * the JDBC driver. Since we rely on the JDBC driver, this "auto-detection" * can only be used for databases that are known to provide accurate meta data. * These currently include Derby, MySQL, Microsoft SQL Server, Oracle, DB2, - * Sybase and PostgreSQL. For any other databases you are required to declare all - * parameters explicitly. You can of course declare all parameters explicitly even - * if the database provides the necessary meta data. In that case your declared - * parameters will take precedence. You can also turn off any meta data processing - * if you want to use parameter names that do not match what is declared during - * the stored procedure compilation. + * Sybase and PostgreSQL. For any other databases you are required to declare + * all parameters explicitly. You can of course declare all parameters + * explicitly even if the database provides the necessary meta data. In that + * case your declared parameters will take precedence. You can also turn off + * any metadata processing if you want to use parameter names that do not + * match what is declared during the stored procedure compilation. * * <p>The actual insert is being handled using Spring's * {@link org.springframework.jdbc.core.JdbcTemplate}. * - * <p>Many of the configuration methods return the current instance of the SimpleJdbcCall - * to provide the ability to chain multiple ones together in a "fluent" interface style. + * <p>Many of the configuration methods return the current instance of the + * SimpleJdbcCall in order to provide the ability to chain multiple ones + * together in a "fluent" interface style. * * @author Thomas Risberg * @since 2.5 @@ -60,8 +61,8 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource; public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOperations { /** - * Constructor that takes one parameter with the JDBC DataSource to use when creating the - * JdbcTemplate. + * Constructor that takes one parameter with the JDBC DataSource to use when + * creating the underlying JdbcTemplate. * @param dataSource the {@code DataSource} to use * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java index 2bae7ec4..d178cc61 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java @@ -118,7 +118,7 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn } @Override - public int execute(Map<String, Object> args) { + public int execute(Map<String, ?> args) { return doExecute(args); } @@ -128,7 +128,7 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn } @Override - public Number executeAndReturnKey(Map<String, Object> args) { + public Number executeAndReturnKey(Map<String, ?> args) { return doExecuteAndReturnKey(args); } @@ -138,7 +138,7 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn } @Override - public KeyHolder executeAndReturnKeyHolder(Map<String, Object> args) { + public KeyHolder executeAndReturnKeyHolder(Map<String, ?> args) { return doExecuteAndReturnKeyHolder(args); } @@ -148,12 +148,12 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn } @Override - public int[] executeBatch(Map<String, Object>[] batch) { + public int[] executeBatch(Map<String, ?>... batch) { return doExecuteBatch(batch); } @Override - public int[] executeBatch(SqlParameterSource[] batch) { + public int[] executeBatch(SqlParameterSource... batch) { return doExecuteBatch(batch); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java index c3bb41cb..0e1dd15c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java @@ -98,7 +98,7 @@ public interface SimpleJdbcInsertOperations { * @param args Map containing column names and corresponding value * @return the number of rows affected as returned by the JDBC driver */ - int execute(Map<String, Object> args); + int execute(Map<String, ?> args); /** * Execute the insert using the values passed in. @@ -115,7 +115,7 @@ public interface SimpleJdbcInsertOperations { * @param args Map containing column names and corresponding value * @return the generated key value */ - Number executeAndReturnKey(Map<String, Object> args); + Number executeAndReturnKey(Map<String, ?> args); /** * Execute the insert using the values passed in and return the generated key. @@ -135,7 +135,7 @@ public interface SimpleJdbcInsertOperations { * @param args Map containing column names and corresponding value * @return the KeyHolder containing all generated keys */ - KeyHolder executeAndReturnKeyHolder(Map<String, Object> args); + KeyHolder executeAndReturnKeyHolder(Map<String, ?> args); /** * Execute the insert using the values passed in and return the generated keys. @@ -152,13 +152,13 @@ public interface SimpleJdbcInsertOperations { * @param batch an array of Maps containing a batch of column names and corresponding value * @return the array of number of rows affected as returned by the JDBC driver */ - int[] executeBatch(Map<String, Object>[] batch); + int[] executeBatch(Map<String, ?>... batch); /** * Execute a batch insert using the batch of values passed in. * @param batch an array of SqlParameterSource containing values for the batch * @return the array of number of rows affected as returned by the JDBC driver */ - int[] executeBatch(SqlParameterSource[] batch); + int[] executeBatch(SqlParameterSource... batch); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/package-info.java index 2dceb5f7..d9403a2c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/package-info.java @@ -1,16 +1,8 @@ /** - * * Simplification layer over JdbcTemplate for Java 5 and above. * * <p>{@code SimpleJdbcInsert} and {@code SimpleJdbcCall} are classes that takes advantage * of database metadata provided by the JDBC driver to simplify the application code. Much of the * parameter specification becomes unnecessary since it can be looked up in the metadata. - * - * Note: The {@code SimpleJdbcOperations} and {@code SimpleJdbcTemplate}, which provides a wrapper - * around JdbcTemplate to take advantage of Java 5 features like generics, varargs and autoboxing, is now deprecated - * since Spring 3.1. All functionality is now available in the {@code JdbcOperations} and - * {@code NamedParametersOperations} respectively. - * */ package org.springframework.jdbc.core.simple; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java index bdcd1c30..ade0a18a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java @@ -19,7 +19,6 @@ package org.springframework.jdbc.core.support; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; - import javax.sql.DataSource; import org.springframework.beans.factory.support.BeanDefinitionRegistry; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.java index 9a83eec3..c0fd9047 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.java @@ -17,7 +17,6 @@ package org.springframework.jdbc.core.support; import java.sql.Connection; - import javax.sql.DataSource; import org.springframework.dao.support.DaoSupport; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/package-info.java index 2ae72099..8f3b9a2a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/package-info.java @@ -1,8 +1,5 @@ /** - * * Classes supporting the {@code org.springframework.jdbc.core} package. * Contains a DAO base class for JdbcTemplate usage. - * */ package org.springframework.jdbc.core.support; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java index 421ecb78..fed12997 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -83,7 +83,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager * <p>This transaction manager can be used as a replacement for the * {@link org.springframework.transaction.jta.JtaTransactionManager} in the single * resource case, as it does not require a container that supports JTA, typically - * in combination with a locally defined JDBC DataSource (e.g. a Jakarta Commons + * in combination with a locally defined JDBC DataSource (e.g. an Apache Commons * DBCP connection pool). Switching between this local strategy and a JTA * environment is just a matter of configuration! * @@ -126,8 +126,8 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan /** * Set the JDBC DataSource that this instance should manage transactions for. - * <p>This will typically be a locally defined DataSource, for example a - * Jakarta Commons DBCP connection pool. Alternatively, you can also drive + * <p>This will typically be a locally defined DataSource, for example an + * Apache Commons DBCP connection pool. Alternatively, you can also drive * transactions for a non-XA J2EE DataSource fetched from JNDI. For an XA * DataSource, use JtaTransactionManager. * <p>The DataSource specified here should be the target DataSource to manage diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java index 7c58f69d..5cad3aa6 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -254,7 +254,7 @@ public abstract class DataSourceUtils { * @see java.sql.Statement#setQueryTimeout */ public static void applyTransactionTimeout(Statement stmt, DataSource dataSource) throws SQLException { - applyTimeout(stmt, dataSource, 0); + applyTimeout(stmt, dataSource, -1); } /** @@ -274,7 +274,7 @@ public abstract class DataSourceUtils { // Remaining transaction timeout overrides specified value. stmt.setQueryTimeout(holder.getTimeToLiveInSeconds()); } - else if (timeout > 0) { + else if (timeout >= 0) { // No current transaction timeout -> apply specified value. stmt.setQueryTimeout(timeout); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java index b272b572..8fcdb5d6 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -53,7 +53,7 @@ import org.springframework.util.ClassUtils; * bean definition to a local DataSource (which is simpler and thus recommended). * * <p>If you need a "real" connection pool outside of a J2EE container, consider - * <a href="http://jakarta.apache.org/commons/dbcp">Apache's Jakarta Commons DBCP</a> + * <a href="http://commons.apache.org/proper/commons-dbcp">Apache Commons DBCP</a> * or <a href="http://sourceforge.net/projects/c3p0">C3P0</a>. * Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full * connection pool beans, supporting the same basic properties as this class diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java index 18c65728..e2d1b0b9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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,6 +16,7 @@ package org.springframework.jdbc.datasource; +import java.sql.SQLException; import java.sql.Savepoint; import org.apache.commons.logging.Log; @@ -41,9 +42,6 @@ import org.springframework.transaction.support.SmartTransactionObject; * will automatically delegate to this, as it autodetects transaction * objects that implement the SavepointManager interface. * - * <p>Note that savepoints are only supported for drivers which - * support JDBC 3.0 or higher. - * * @author Juergen Hoeller * @since 1.1 */ @@ -109,15 +107,9 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager, throw new NestedTransactionNotSupportedException( "Cannot create a nested transaction because savepoints are not supported by your JDBC driver"); } - } - catch (Throwable ex) { - throw new NestedTransactionNotSupportedException( - "Cannot create a nested transaction because your JDBC driver is not a JDBC 3.0 driver", ex); - } - try { return conHolder.createSavepoint(); } - catch (Throwable ex) { + catch (SQLException ex) { throw new CannotCreateTransactionException("Could not create JDBC savepoint", ex); } } @@ -128,8 +120,9 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager, */ @Override public void rollbackToSavepoint(Object savepoint) throws TransactionException { + ConnectionHolder conHolder = getConnectionHolderForSavepoint(); try { - getConnectionHolderForSavepoint().getConnection().rollback((Savepoint) savepoint); + conHolder.getConnection().rollback((Savepoint) savepoint); } catch (Throwable ex) { throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex); @@ -142,8 +135,9 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager, */ @Override public void releaseSavepoint(Object savepoint) throws TransactionException { + ConnectionHolder conHolder = getConnectionHolderForSavepoint(); try { - getConnectionHolderForSavepoint().getConnection().releaseSavepoint((Savepoint) savepoint); + conHolder.getConnection().releaseSavepoint((Savepoint) savepoint); } catch (Throwable ex) { logger.debug("Could not explicitly release JDBC savepoint", ex); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java index aae634f2..73433728 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -26,8 +26,8 @@ import org.springframework.util.Assert; /** * Simple implementation of the standard JDBC {@link javax.sql.DataSource} interface, - * configuring a plain old JDBC {@link java.sql.Driver} via bean properties, and returning - * a new {@link java.sql.Connection} from every {@code getConnection} call. + * configuring a plain old JDBC {@link java.sql.Driver} via bean properties, and + * returning a new {@link java.sql.Connection} from every {@code getConnection} call. * * <p><b>NOTE: This class is not an actual connection pool; it does not actually * pool Connections.</b> It just serves as simple replacement for a full-blown @@ -40,7 +40,7 @@ import org.springframework.util.Assert; * for seamless switching to and from a local DataSource bean like this class. * * <p>If you need a "real" connection pool outside of a J2EE container, consider - * <a href="http://jakarta.apache.org/commons/dbcp">Apache's Jakarta Commons DBCP</a> + * <a href="http://commons.apache.org/proper/commons-dbcp">Apache Commons DBCP</a> * or <a href="http://sourceforge.net/projects/c3p0">C3P0</a>. * Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full * connection pool beans, supporting the same basic properties as this class diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SmartDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SmartDataSource.java index 93e59f66..e6aa2061 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SmartDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SmartDataSource.java @@ -17,7 +17,6 @@ package org.springframework.jdbc.datasource; import java.sql.Connection; - import javax.sql.DataSource; /** diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java index 2497a6cc..6fc983f1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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,7 +18,6 @@ package org.springframework.jdbc.datasource.embedded; import java.sql.Connection; import java.sql.SQLException; -import java.sql.Statement; import javax.sql.DataSource; import org.apache.commons.logging.Log; @@ -35,16 +34,25 @@ abstract class AbstractEmbeddedDatabaseConfigurer implements EmbeddedDatabaseCon protected final Log logger = LogFactory.getLog(getClass()); + @Override public void shutdown(DataSource dataSource, String databaseName) { + Connection con = null; try { - Connection connection = dataSource.getConnection(); - Statement stmt = connection.createStatement(); - stmt.execute("SHUTDOWN"); + con = dataSource.getConnection(); + con.createStatement().execute("SHUTDOWN"); } catch (SQLException ex) { - if (logger.isWarnEnabled()) { - logger.warn("Could not shutdown embedded database", ex); + logger.warn("Could not shut down embedded database", ex); + } + finally { + if (con != null) { + try { + con.close(); + } + catch (Throwable ex) { + logger.debug("Could not close JDBC Connection on shutdown", ex); + } } } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java index 08ee1687..8e94ae3b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.java @@ -193,7 +193,6 @@ public class EmbeddedDatabaseBuilder { * @return {@code this}, to facilitate method chaining * @since 4.0.3 * @see #setBlockCommentEndDelimiter - * @since 4.0.3 */ public EmbeddedDatabaseBuilder setBlockCommentStartDelimiter(String blockCommentStartDelimiter) { this.databasePopulator.setBlockCommentStartDelimiter(blockCommentStartDelimiter); @@ -207,7 +206,6 @@ public class EmbeddedDatabaseBuilder { * @return {@code this}, to facilitate method chaining * @since 4.0.3 * @see #setBlockCommentStartDelimiter - * @since 4.0.3 */ public EmbeddedDatabaseBuilder setBlockCommentEndDelimiter(String blockCommentEndDelimiter) { this.databasePopulator.setBlockCommentEndDelimiter(blockCommentEndDelimiter); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java index 309d7765..81e4df01 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.java @@ -17,7 +17,6 @@ package org.springframework.jdbc.datasource.embedded; import java.sql.Driver; - import javax.sql.DataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/package-info.java index 4349f9d2..4cb074c5 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/package-info.java @@ -1,8 +1,4 @@ - /** - * * Provides extensible support for creating embedded database instances. - * */ package org.springframework.jdbc.datasource.embedded; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java index 16c7b8e0..1b74ac00 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java @@ -18,7 +18,6 @@ package org.springframework.jdbc.datasource.init; import java.sql.Connection; import java.sql.SQLException; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java index b6b9f2d2..d72ee0ca 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java @@ -40,7 +40,7 @@ public interface DatabasePopulator { * {@link ResourceDatabasePopulator} and {@link DatabasePopulatorUtils} wrap * all {@code SQLExceptions} in {@code ScriptExceptions}. * @param connection the JDBC connection to use to populate the db; already - * configured and ready to use + * configured and ready to use; never {@code null} * @throws SQLException if an unrecoverable data access exception occurs * during database population * @throws ScriptException in all other error cases diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java index 898c6a39..31fb497c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulatorUtils.java @@ -17,7 +17,6 @@ package org.springframework.jdbc.datasource.init; import java.sql.Connection; - import javax.sql.DataSource; import org.springframework.dao.DataAccessException; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java index 23082390..56737400 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java @@ -20,18 +20,24 @@ 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; import org.springframework.core.io.support.EncodedResource; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** - * Populates or initializes a database from SQL scripts defined in external - * resources. + * Populates, initializes, or cleans up a database using SQL scripts defined in + * external resources. * - * <p>Call {@link #addScript(Resource)} to add a single SQL script location. - * Call {@link #addScripts(Resource...)} to add multiple SQL script locations. - * Call {@link #setSqlScriptEncoding(String)} to set the encoding for all added - * scripts. + * <ul> + * <li>Call {@link #addScript} to add a single SQL script location. + * <li>Call {@link #addScripts} to add multiple SQL script locations. + * <li>Consult the setter methods in this class for further configuration options. + * <li>Call {@link #populate} or {@link #execute} to initialize or clean up the + * database using the configured scripts. + * </ul> * * @author Keith Donald * @author Dave Syer @@ -42,6 +48,7 @@ import org.springframework.core.io.support.EncodedResource; * @author Chris Baldwin * @since 3.0 * @see DatabasePopulatorUtils + * @see ScriptUtils */ public class ResourceDatabasePopulator implements DatabasePopulator { @@ -73,12 +80,13 @@ public class ResourceDatabasePopulator implements DatabasePopulator { /** * Construct a new {@code ResourceDatabasePopulator} with default settings * for the supplied scripts. - * @param scripts the scripts to execute to initialize or populate the database + * @param scripts the scripts to execute to initialize or clean up the database; + * never {@code null} * @since 4.0.3 */ public ResourceDatabasePopulator(Resource... scripts) { this(); - this.scripts = Arrays.asList(scripts); + setScripts(scripts); } /** @@ -87,9 +95,10 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * logged but not cause a failure * @param ignoreFailedDrops flag to indicate that a failed SQL {@code DROP} * statement can be ignored - * @param sqlScriptEncoding the encoding for the supplied SQL scripts, if - * different from the platform encoding; may be {@code null} - * @param scripts the scripts to execute to initialize or populate the database + * @param sqlScriptEncoding the encoding for the supplied SQL scripts; may + * be {@code null} or <em>empty</em> to indicate platform encoding + * @param scripts the scripts to execute to initialize or clean up the database; + * never {@code null} * @since 4.0.3 */ public ResourceDatabasePopulator(boolean continueOnError, boolean ignoreFailedDrops, String sqlScriptEncoding, @@ -97,41 +106,47 @@ public class ResourceDatabasePopulator implements DatabasePopulator { this(scripts); this.continueOnError = continueOnError; this.ignoreFailedDrops = ignoreFailedDrops; - this.sqlScriptEncoding = sqlScriptEncoding; + setSqlScriptEncoding(sqlScriptEncoding); } /** - * Add a script to execute to initialize or populate the database. - * @param script the path to an SQL script + * Add a script to execute to initialize or clean up the database. + * @param script the path to an SQL script; never {@code null} */ public void addScript(Resource script) { - this.scripts.add(script); + Assert.notNull(script, "Script must not be null"); + getScripts().add(script); } /** - * Add multiple scripts to execute to initialize or populate the database. - * @param scripts the scripts to execute + * Add multiple scripts to execute to initialize or clean up the database. + * @param scripts the scripts to execute; never {@code null} */ public void addScripts(Resource... scripts) { - this.scripts.addAll(Arrays.asList(scripts)); + assertContentsOfScriptArray(scripts); + getScripts().addAll(Arrays.asList(scripts)); } /** - * Set the scripts to execute to initialize or populate the database, + * Set the scripts to execute to initialize or clean up the database, * replacing any previously added scripts. - * @param scripts the scripts to execute + * @param scripts the scripts to execute; never {@code null} */ public void setScripts(Resource... scripts) { - this.scripts = Arrays.asList(scripts); + assertContentsOfScriptArray(scripts); + // Ensure that the list is modifiable + this.scripts = new ArrayList<Resource>(Arrays.asList(scripts)); } /** - * Specify the encoding for SQL scripts, if different from the platform encoding. - * @param sqlScriptEncoding the encoding used in scripts + * Specify the encoding for the configured SQL scripts, if different from the + * platform encoding. + * @param sqlScriptEncoding the encoding used in scripts; may be {@code null} + * or empty to indicate platform encoding * @see #addScript(Resource) */ public void setSqlScriptEncoding(String sqlScriptEncoding) { - this.sqlScriptEncoding = sqlScriptEncoding; + this.sqlScriptEncoding = StringUtils.hasText(sqlScriptEncoding) ? sqlScriptEncoding : null; } /** @@ -158,11 +173,13 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * Set the start delimiter that identifies block comments within the SQL * scripts. * <p>Defaults to {@code "/*"}. - * @param blockCommentStartDelimiter the start delimiter for block comments + * @param blockCommentStartDelimiter the start delimiter for block comments; + * never {@code null} or empty * @since 4.0.3 * @see #setBlockCommentEndDelimiter */ public void setBlockCommentStartDelimiter(String blockCommentStartDelimiter) { + Assert.hasText(blockCommentStartDelimiter, "BlockCommentStartDelimiter must not be null or empty"); this.blockCommentStartDelimiter = blockCommentStartDelimiter; } @@ -170,11 +187,13 @@ public class ResourceDatabasePopulator implements DatabasePopulator { * Set the end delimiter that identifies block comments within the SQL * scripts. * <p>Defaults to <code>"*/"</code>. - * @param blockCommentEndDelimiter the end delimiter for block comments + * @param blockCommentEndDelimiter the end delimiter for block comments; + * never {@code null} or empty * @since 4.0.3 * @see #setBlockCommentStartDelimiter */ public void setBlockCommentEndDelimiter(String blockCommentEndDelimiter) { + Assert.hasText(blockCommentEndDelimiter, "BlockCommentEndDelimiter must not be null or empty"); this.blockCommentEndDelimiter = blockCommentEndDelimiter; } @@ -189,10 +208,10 @@ public class ResourceDatabasePopulator implements DatabasePopulator { /** * Flag to indicate that a failed SQL {@code DROP} statement can be ignored. - * <p>This is useful for non-embedded databases whose SQL dialect does not support an - * {@code IF EXISTS} clause in a {@code DROP} statement. + * <p>This is useful for a non-embedded database whose SQL dialect does not + * support an {@code IF EXISTS} clause in a {@code DROP} statement. * <p>The default is {@code false} so that if the populator runs accidentally, it will - * fail fast if the script starts with a {@code DROP} statement. + * fail fast if a script starts with a {@code DROP} statement. * @param ignoreFailedDrops {@code true} if failed drop statements should be ignored */ public void setIgnoreFailedDrops(boolean ignoreFailedDrops) { @@ -201,10 +220,12 @@ public class ResourceDatabasePopulator implements DatabasePopulator { /** * {@inheritDoc} + * @see #execute(DataSource) */ @Override public void populate(Connection connection) throws ScriptException { - for (Resource script : this.scripts) { + Assert.notNull(connection, "Connection must not be null"); + for (Resource script : getScripts()) { ScriptUtils.executeSqlScript(connection, encodeScript(script), this.continueOnError, this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter, this.blockCommentEndDelimiter); @@ -212,11 +233,37 @@ public class ResourceDatabasePopulator implements DatabasePopulator { } /** + * Execute this {@code ResourceDatabasePopulator} against the given + * {@link DataSource}. + * <p>Delegates to {@link DatabasePopulatorUtils#execute}. + * @param dataSource the {@code DataSource} to execute against; never {@code null} + * @throws ScriptException if an error occurs + * @since 4.1 + * @see #populate(Connection) + */ + public void execute(DataSource dataSource) throws ScriptException { + Assert.notNull(dataSource, "DataSource must not be null"); + DatabasePopulatorUtils.execute(this, dataSource); + } + + final List<Resource> getScripts() { + return this.scripts; + } + + /** * {@link EncodedResource} is not a sub-type of {@link Resource}. Thus we - * always need to wrap each script resource in an encoded resource. + * always need to wrap each script resource in an {@code EncodedResource} + * using the configured {@linkplain #setSqlScriptEncoding encoding}. + * @param script the script to wrap; never {@code null} */ private EncodedResource encodeScript(Resource script) { + Assert.notNull(script, "Script must not be null"); return new EncodedResource(script, this.sqlScriptEncoding); } + private void assertContentsOfScriptArray(Resource... scripts) { + Assert.notNull(scripts, "Scripts must not be null"); + Assert.noNullElements(scripts, "Scripts array must not contain null elements"); + } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptException.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptException.java index 198284d1..2071221e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptException.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptException.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptStatementFailedException.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptStatementFailedException.java index 77c49a1c..47e922e8 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptStatementFailedException.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptStatementFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -31,14 +31,14 @@ public class ScriptStatementFailedException extends ScriptException { /** * Construct a new {@code ScriptStatementFailedException}. - * @param statement the actual SQL statement that failed - * @param lineNumber the line number in the SQL script + * @param stmt the actual SQL statement that failed + * @param stmtNumber the statement number in the SQL script (i.e., + * the nth statement present in the resource) * @param resource the resource from which the SQL statement was read * @param cause the underlying cause of the failure */ - public ScriptStatementFailedException(String statement, int lineNumber, EncodedResource resource, Throwable cause) { - super("Failed to execute SQL script statement at line " + lineNumber + " of resource " + resource + ": " - + statement, cause); + public ScriptStatementFailedException(String stmt, int stmtNumber, EncodedResource resource, Throwable cause) { + super("Failed to execute SQL script statement #" + stmtNumber + " of resource " + resource + ": " + stmt, cause); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java index 9f23e009..00894080 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -26,6 +26,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; import org.springframework.util.Assert; @@ -47,22 +48,20 @@ import org.springframework.util.StringUtils; */ public abstract class ScriptUtils { - private static final Log logger = LogFactory.getLog(ScriptUtils.class); - /** - * Default statement separator within SQL scripts. + * Default statement separator within SQL scripts: {@code ";"}. */ public static final String DEFAULT_STATEMENT_SEPARATOR = ";"; /** - * Fallback statement separator within SQL scripts. - * <p>Used if neither a custom defined separator nor the + * Fallback statement separator within SQL scripts: {@code "\n"}. + * <p>Used if neither a custom separator nor the * {@link #DEFAULT_STATEMENT_SEPARATOR} is present in a given script. */ public static final String FALLBACK_STATEMENT_SEPARATOR = "\n"; /** - * End of file (EOF) SQL statement separator. + * End of file (EOF) SQL statement separator: {@code "^^^ END OF SCRIPT ^^^"}. * <p>This value may be supplied as the {@code separator} to {@link * #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String)} * to denote that an SQL script contains a single statement (potentially @@ -73,27 +72,23 @@ public abstract class ScriptUtils { public static final String EOF_STATEMENT_SEPARATOR = "^^^ END OF SCRIPT ^^^"; /** - * Default prefix for line comments within SQL scripts. + * Default prefix for single-line comments within SQL scripts: {@code "--"}. */ public static final String DEFAULT_COMMENT_PREFIX = "--"; /** - * Default start delimiter for block comments within SQL scripts. + * Default start delimiter for block comments within SQL scripts: {@code "/*"}. */ public static final String DEFAULT_BLOCK_COMMENT_START_DELIMITER = "/*"; /** - * Default end delimiter for block comments within SQL scripts. + * Default end delimiter for block comments within SQL scripts: <code>"*/"</code>. */ public static final String DEFAULT_BLOCK_COMMENT_END_DELIMITER = "*/"; - /** - * Prevent instantiation of this utility class. - */ - private ScriptUtils() { - /* no-op */ - } + private static final Log logger = LogFactory.getLog(ScriptUtils.class); + /** * Split an SQL script into separate statements delimited by the provided @@ -139,7 +134,7 @@ public abstract class ScriptUtils { */ public static void splitSqlScript(String script, String separator, List<String> statements) throws ScriptException { splitSqlScript(null, script, separator, DEFAULT_COMMENT_PREFIX, DEFAULT_BLOCK_COMMENT_START_DELIMITER, - DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements); + DEFAULT_BLOCK_COMMENT_END_DELIMITER, statements); } /** @@ -275,6 +270,7 @@ public abstract class ScriptUtils { */ private static String readScript(EncodedResource resource, String commentPrefix, String separator) throws IOException { + LineNumberReader lnr = new LineNumberReader(resource.getReader()); try { return readScript(lnr, commentPrefix, separator); @@ -301,6 +297,7 @@ public abstract class ScriptUtils { */ public static String readScript(LineNumberReader lineNumberReader, String commentPrefix, String separator) throws IOException { + String currentStatement = lineNumberReader.readLine(); StringBuilder scriptBuilder = new StringBuilder(); while (currentStatement != null) { @@ -351,8 +348,8 @@ public abstract class ScriptUtils { } /** - * Execute the given SQL script using default settings for separator separators, - * comment delimiters, and exception handling flags. + * Execute the given SQL script using default settings for statement + * separators, comment delimiters, and exception handling flags. * <p>Statement separators and comments will be removed before executing * individual statements within the supplied script. * <p><b>Do not use this method to execute DDL if you expect rollback.</b> @@ -362,8 +359,8 @@ public abstract class ScriptUtils { * current platform's default encoding * @throws ScriptException if an error occurred while executing the SQL script * @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String) - * @see #DEFAULT_COMMENT_PREFIX * @see #DEFAULT_STATEMENT_SEPARATOR + * @see #DEFAULT_COMMENT_PREFIX * @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER * @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER */ @@ -372,8 +369,8 @@ public abstract class ScriptUtils { } /** - * Execute the given SQL script using default settings for separator separators, - * comment delimiters, and exception handling flags. + * Execute the given SQL script using default settings for statement + * separators, comment delimiters, and exception handling flags. * <p>Statement separators and comments will be removed before executing * individual statements within the supplied script. * <p><b>Do not use this method to execute DDL if you expect rollback.</b> @@ -383,8 +380,8 @@ public abstract class ScriptUtils { * to load the SQL script from * @throws ScriptException if an error occurred while executing the SQL script * @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String) - * @see #DEFAULT_COMMENT_PREFIX * @see #DEFAULT_STATEMENT_SEPARATOR + * @see #DEFAULT_COMMENT_PREFIX * @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER * @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER */ @@ -406,8 +403,8 @@ public abstract class ScriptUtils { * in the event of an error * @param ignoreFailedDrops whether or not to continue in the event of specifically * an error on a {@code DROP} statement - * @param commentPrefix the prefix that identifies comments in the SQL script — - * typically "--" + * @param commentPrefix the prefix that identifies single-line comments in the + * SQL script — typically "--" * @param separator the script statement separator; defaults to * {@value #DEFAULT_STATEMENT_SEPARATOR} if not specified and falls back to * {@value #FALLBACK_STATEMENT_SEPARATOR} as a last resort; may be set to @@ -430,9 +427,8 @@ public abstract class ScriptUtils { if (logger.isInfoEnabled()) { logger.info("Executing SQL script from " + resource); } - long startTime = System.currentTimeMillis(); - List<String> statements = new LinkedList<String>(); + String script; try { script = readScript(resource, commentPrefix, separator); @@ -448,13 +444,15 @@ public abstract class ScriptUtils { separator = FALLBACK_STATEMENT_SEPARATOR; } + List<String> statements = new LinkedList<String>(); splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter, - blockCommentEndDelimiter, statements); - int lineNumber = 0; + blockCommentEndDelimiter, statements); + + int stmtNumber = 0; Statement stmt = connection.createStatement(); try { for (String statement : statements) { - lineNumber++; + stmtNumber++; try { stmt.execute(statement); int rowsAffected = stmt.getUpdateCount(); @@ -466,12 +464,12 @@ public abstract class ScriptUtils { boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); if (continueOnError || (dropStatement && ignoreFailedDrops)) { if (logger.isDebugEnabled()) { - logger.debug("Failed to execute SQL script statement at line " + lineNumber - + " of resource " + resource + ": " + statement, ex); + logger.debug("Failed to execute SQL script statement #" + stmtNumber + + " of resource " + resource + ": " + statement, ex); } } else { - throw new ScriptStatementFailedException(statement, lineNumber, resource, ex); + throw new ScriptStatementFailedException(statement, stmtNumber, resource, ex); } } } @@ -494,7 +492,6 @@ public abstract class ScriptUtils { if (ex instanceof ScriptException) { throw (ScriptException) ex; } - throw new UncategorizedScriptException( "Failed to execute database script from resource [" + resource + "]", ex); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/package-info.java index 0e849199..ff831a91 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/package-info.java @@ -1,6 +1,4 @@ - /** * Provides extensible support for initializing databases through scripts. */ package org.springframework.jdbc.datasource.init; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/package-info.java index bc6d3036..e7f32d33 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/package-info.java @@ -1,8 +1,4 @@ - /** - * * Provides a strategy for looking up JDBC DataSources by name. - * */ package org.springframework.jdbc.datasource.lookup; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/package-info.java index 704c4a3b..9dce44a2 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/package-info.java @@ -1,10 +1,6 @@ - /** - * * Provides a utility class for easy DataSource access, * a PlatformTransactionManager for a single DataSource, * and various simple DataSource implementations. - * */ package org.springframework.jdbc.datasource; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/GenericSqlQuery.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/GenericSqlQuery.java index 6854921d..d2af6281 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/GenericSqlQuery.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/GenericSqlQuery.java @@ -18,9 +18,9 @@ package org.springframework.jdbc.object; import java.util.Map; +import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.jdbc.core.RowMapper; import org.springframework.util.Assert; -import org.springframework.dao.InvalidDataAccessResourceUsageException; public class GenericSqlQuery<T> extends SqlQuery<T> { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java index 61c52338..73922190 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -81,7 +81,7 @@ public abstract class RdbmsOperation implements InitializingBean { * least checking that a DataSource and sql have been provided, * but subclasses may also implement their own custom validation. */ - private boolean compiled; + private volatile boolean compiled; /** @@ -350,7 +350,7 @@ public abstract class RdbmsOperation implements InitializingBean { * Is this operation "compiled"? Compilation, as in JDO, * means that the operation is fully configured, and ready to use. * The exact meaning of compilation will vary between subclasses. - * @return whether this operation is compiled, and ready to use. + * @return whether this operation is compiled and ready to use */ public boolean isCompiled() { return this.compiled; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java index ea4d8582..93bbc680 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.java @@ -18,7 +18,6 @@ package org.springframework.jdbc.object; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.springframework.dao.DataAccessException; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/UpdatableSqlQuery.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/UpdatableSqlQuery.java index 7f4acdbc..081504f9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/UpdatableSqlQuery.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/UpdatableSqlQuery.java @@ -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; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/package-info.java index 267a785b..6bbe5166 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/package-info.java @@ -1,5 +1,4 @@ /** - * * The classes in this package represent RDBMS queries, updates, * and stored procedures as threadsafe, reusable objects. This approach * is modelled by JDO, although of course objects returned by queries @@ -14,7 +13,5 @@ * <p>This package and related packages are discussed in Chapter 9 of * <a href="http://www.amazon.com/exec/obidos/tg/detail/-/0764543857/">Expert One-On-One J2EE Design and Development</a> * by Rod Johnson (Wrox, 2002). - * */ package org.springframework.jdbc.object; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/package-info.java index 662b09ff..1a05b52b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/package-info.java @@ -1,6 +1,4 @@ - /** - * * The classes in this package make JDBC easier to use and * reduce the likelihood of common errors. In particular, they: * <ul> @@ -18,7 +16,5 @@ * <p>This package and related packages are discussed in Chapter 9 of * <a href="http://www.amazon.com/exec/obidos/tg/detail/-/0764543857/">Expert One-On-One J2EE Design and Development</a> * by Rod Johnson (Wrox, 2002). - * */ package org.springframework.jdbc; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/CustomSQLErrorCodesTranslation.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/CustomSQLErrorCodesTranslation.java index 77275108..6f543c5d 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/CustomSQLErrorCodesTranslation.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/CustomSQLErrorCodesTranslation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2014 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,7 +38,7 @@ public class CustomSQLErrorCodesTranslation { /** * Set the SQL error codes to match. */ - public void setErrorCodes(String[] errorCodes) { + public void setErrorCodes(String... errorCodes) { this.errorCodes = StringUtils.sortStringArray(errorCodes); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/DatabaseStartupValidator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/DatabaseStartupValidator.java index 738709ac..e5b11349 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/DatabaseStartupValidator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/DatabaseStartupValidator.java @@ -19,7 +19,6 @@ package org.springframework.jdbc.support; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; - import javax.sql.DataSource; import org.apache.commons.logging.Log; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java index ea6be1ab..5995ce4a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -26,9 +26,9 @@ import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; import java.sql.Types; - import javax.sql.DataSource; import org.apache.commons.logging.Log; @@ -36,6 +36,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.lang.UsesJava7; +import org.springframework.util.ClassUtils; /** * Generic utility methods for working with JDBC. Mainly for internal use @@ -53,6 +55,10 @@ public abstract class JdbcUtils { public static final int TYPE_UNKNOWN = Integer.MIN_VALUE; + // Check for JDBC 4.1 getObject(int, Class) method - available on JDK 7 and higher + private static final boolean getObjectWithTypeAvailable = + ClassUtils.hasMethod(ResultSet.class, "getObject", int.class, Class.class); + private static final Log logger = LogFactory.getLog(JdbcUtils.class); @@ -129,86 +135,90 @@ public abstract class JdbcUtils { * @return the value object * @throws SQLException if thrown by the JDBC API */ + @UsesJava7 // guard optional use of JDBC 4.1 (safe with 1.6 due to getObjectWithTypeAvailable check) public static Object getResultSetValue(ResultSet rs, int index, Class<?> requiredType) throws SQLException { if (requiredType == null) { return getResultSetValue(rs, index); } - Object value = null; - boolean wasNullCheck = false; + Object value; // Explicitly extract typed value, as far as possible. if (String.class.equals(requiredType)) { - value = rs.getString(index); + return rs.getString(index); } else if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) { value = rs.getBoolean(index); - wasNullCheck = true; } else if (byte.class.equals(requiredType) || Byte.class.equals(requiredType)) { value = rs.getByte(index); - wasNullCheck = true; } else if (short.class.equals(requiredType) || Short.class.equals(requiredType)) { value = rs.getShort(index); - wasNullCheck = true; } else if (int.class.equals(requiredType) || Integer.class.equals(requiredType)) { value = rs.getInt(index); - wasNullCheck = true; } else if (long.class.equals(requiredType) || Long.class.equals(requiredType)) { value = rs.getLong(index); - wasNullCheck = true; } else if (float.class.equals(requiredType) || Float.class.equals(requiredType)) { value = rs.getFloat(index); - wasNullCheck = true; } else if (double.class.equals(requiredType) || Double.class.equals(requiredType) || Number.class.equals(requiredType)) { value = rs.getDouble(index); - wasNullCheck = true; } - else if (byte[].class.equals(requiredType)) { - value = rs.getBytes(index); + else if (BigDecimal.class.equals(requiredType)) { + return rs.getBigDecimal(index); } else if (java.sql.Date.class.equals(requiredType)) { - value = rs.getDate(index); + return rs.getDate(index); } else if (java.sql.Time.class.equals(requiredType)) { - value = rs.getTime(index); + return rs.getTime(index); } else if (java.sql.Timestamp.class.equals(requiredType) || java.util.Date.class.equals(requiredType)) { - value = rs.getTimestamp(index); + return rs.getTimestamp(index); } - else if (BigDecimal.class.equals(requiredType)) { - value = rs.getBigDecimal(index); + else if (byte[].class.equals(requiredType)) { + return rs.getBytes(index); } else if (Blob.class.equals(requiredType)) { - value = rs.getBlob(index); + return rs.getBlob(index); } else if (Clob.class.equals(requiredType)) { - value = rs.getClob(index); + return rs.getClob(index); } else { // Some unknown type desired -> rely on getObject. - value = getResultSetValue(rs, index); + if (getObjectWithTypeAvailable) { + try { + return rs.getObject(index, requiredType); + } + catch (AbstractMethodError err) { + logger.debug("JDBC driver does not implement JDBC 4.1 'getObject(int, Class)' method", err); + } + catch (SQLFeatureNotSupportedException ex) { + logger.debug("JDBC driver does not support JDBC 4.1 'getObject(int, Class)' method", ex); + } + catch (SQLException ex) { + logger.debug("JDBC driver has limited support for JDBC 4.1 'getObject(int, Class)' method", ex); + } + } + // Fall back to getObject without type specification... + return getResultSetValue(rs, index); } - // Perform was-null check if demanded (for results that the - // JDBC driver returns as primitives). - if (wasNullCheck && value != null && rs.wasNull()) { - value = null; - } - return value; + // Perform was-null check if necessary (for results that the JDBC driver returns as primitives). + return (rs.wasNull() ? null : value); } /** * Retrieve a JDBC column value from a ResultSet, using the most appropriate * value type. The returned value should be a detached value object, not having * any ties to the active ResultSet: in particular, it should not be a Blob or - * Clob object but rather a byte array respectively String representation. + * Clob object but rather a byte array or String representation, respectively. * <p>Uses the {@code getObject(index)} method, but includes additional "hacks" * to get around Oracle 10g returning a non-standard object for its TIMESTAMP * datatype and a {@code java.sql.Date} for DATE columns leaving out the @@ -229,20 +239,19 @@ public abstract class JdbcUtils { className = obj.getClass().getName(); } if (obj instanceof Blob) { - obj = rs.getBytes(index); + Blob blob = (Blob) obj; + obj = blob.getBytes(1, (int) blob.length()); } else if (obj instanceof Clob) { - obj = rs.getString(index); + Clob clob = (Clob) obj; + obj = clob.getSubString(1, (int) clob.length()); } - else if (className != null && - ("oracle.sql.TIMESTAMP".equals(className) || - "oracle.sql.TIMESTAMPTZ".equals(className))) { + else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) { obj = rs.getTimestamp(index); } else if (className != null && className.startsWith("oracle.sql.DATE")) { String metaDataClassName = rs.getMetaData().getColumnClassName(index); - if ("java.sql.Timestamp".equals(metaDataClassName) || - "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { + if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { obj = rs.getTimestamp(index); } else { @@ -371,9 +380,6 @@ public abstract class JdbcUtils { catch (SQLException ex) { logger.debug("JDBC driver 'supportsBatchUpdates' method threw exception", ex); } - catch (AbstractMethodError err) { - logger.debug("JDBC driver does not support JDBC 2.0 'supportsBatchUpdates' method", err); - } return false; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.java index a074133f..7a9c1399 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -79,7 +79,7 @@ public class SQLErrorCodes { * Set this property to specify multiple database names that contains spaces, * in which case we can not use bean names for lookup. */ - public void setDatabaseProductNames(String[] databaseProductNames) { + public void setDatabaseProductNames(String... databaseProductNames) { this.databaseProductNames = databaseProductNames; } @@ -99,7 +99,7 @@ public class SQLErrorCodes { return this.useSqlStateForTranslation; } - public void setBadSqlGrammarCodes(String[] badSqlGrammarCodes) { + public void setBadSqlGrammarCodes(String... badSqlGrammarCodes) { this.badSqlGrammarCodes = StringUtils.sortStringArray(badSqlGrammarCodes); } @@ -107,7 +107,7 @@ public class SQLErrorCodes { return this.badSqlGrammarCodes; } - public void setInvalidResultSetAccessCodes(String[] invalidResultSetAccessCodes) { + public void setInvalidResultSetAccessCodes(String... invalidResultSetAccessCodes) { this.invalidResultSetAccessCodes = StringUtils.sortStringArray(invalidResultSetAccessCodes); } @@ -119,11 +119,11 @@ public class SQLErrorCodes { return duplicateKeyCodes; } - public void setDuplicateKeyCodes(String[] duplicateKeyCodes) { + public void setDuplicateKeyCodes(String... duplicateKeyCodes) { this.duplicateKeyCodes = duplicateKeyCodes; } - public void setDataIntegrityViolationCodes(String[] dataIntegrityViolationCodes) { + public void setDataIntegrityViolationCodes(String... dataIntegrityViolationCodes) { this.dataIntegrityViolationCodes = StringUtils.sortStringArray(dataIntegrityViolationCodes); } @@ -131,7 +131,7 @@ public class SQLErrorCodes { return this.dataIntegrityViolationCodes; } - public void setPermissionDeniedCodes(String[] permissionDeniedCodes) { + public void setPermissionDeniedCodes(String... permissionDeniedCodes) { this.permissionDeniedCodes = StringUtils.sortStringArray(permissionDeniedCodes); } @@ -139,7 +139,7 @@ public class SQLErrorCodes { return this.permissionDeniedCodes; } - public void setDataAccessResourceFailureCodes(String[] dataAccessResourceFailureCodes) { + public void setDataAccessResourceFailureCodes(String... dataAccessResourceFailureCodes) { this.dataAccessResourceFailureCodes = StringUtils.sortStringArray(dataAccessResourceFailureCodes); } @@ -147,7 +147,7 @@ public class SQLErrorCodes { return this.dataAccessResourceFailureCodes; } - public void setTransientDataAccessResourceCodes(String[] transientDataAccessResourceCodes) { + public void setTransientDataAccessResourceCodes(String... transientDataAccessResourceCodes) { this.transientDataAccessResourceCodes = StringUtils.sortStringArray(transientDataAccessResourceCodes); } @@ -155,7 +155,7 @@ public class SQLErrorCodes { return this.transientDataAccessResourceCodes; } - public void setCannotAcquireLockCodes(String[] cannotAcquireLockCodes) { + public void setCannotAcquireLockCodes(String... cannotAcquireLockCodes) { this.cannotAcquireLockCodes = StringUtils.sortStringArray(cannotAcquireLockCodes); } @@ -163,7 +163,7 @@ public class SQLErrorCodes { return this.cannotAcquireLockCodes; } - public void setDeadlockLoserCodes(String[] deadlockLoserCodes) { + public void setDeadlockLoserCodes(String... deadlockLoserCodes) { this.deadlockLoserCodes = StringUtils.sortStringArray(deadlockLoserCodes); } @@ -171,7 +171,7 @@ public class SQLErrorCodes { return this.deadlockLoserCodes; } - public void setCannotSerializeTransactionCodes(String[] cannotSerializeTransactionCodes) { + public void setCannotSerializeTransactionCodes(String... cannotSerializeTransactionCodes) { this.cannotSerializeTransactionCodes = StringUtils.sortStringArray(cannotSerializeTransactionCodes); } @@ -179,7 +179,7 @@ public class SQLErrorCodes { return this.cannotSerializeTransactionCodes; } - public void setCustomTranslations(CustomSQLErrorCodesTranslation[] customTranslations) { + public void setCustomTranslations(CustomSQLErrorCodesTranslation... customTranslations) { this.customTranslations = customTranslations; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java index 0fc68068..1cd9144f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -24,6 +24,7 @@ import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.QueryTimeoutException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; @@ -87,6 +88,7 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException @Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { + // First, the getSQLState check... String sqlState = getSqlState(ex); if (sqlState != null && sqlState.length() >= 2) { String classCode = sqlState.substring(0, 2); @@ -109,6 +111,14 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException return new ConcurrencyFailureException(buildMessage(task, sql, ex), ex); } } + + // For MySQL: exception class name indicating a timeout? + // (since MySQL doesn't throw the JDBC 4 SQLTimeoutException) + if (ex.getClass().getName().contains("Timeout")) { + return new QueryTimeoutException(buildMessage(task, sql, ex), ex); + } + + // Couldn't resolve anything proper - resort to UncategorizedSQLException. return null; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java new file mode 100644 index 00000000..d9b38ac7 --- /dev/null +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java @@ -0,0 +1,163 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.support.incrementer; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import javax.sql.DataSource; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.jdbc.support.JdbcUtils; + +/** + * Abstract base class for {@link DataFieldMaxValueIncrementer} implementations + * which are based on identity columns in a sequence-like table. + * + * @author Juergen Hoeller + * @author Thomas Risberg + * @since 4.1.2 + */ +public abstract class AbstractIdentityColumnMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { + + private boolean deleteSpecificValues = false; + + /** The current cache of values */ + private long[] valueCache; + + /** The next id to serve from the value cache */ + private int nextValueIndex = -1; + + + /** + * Default constructor for bean property style usage. + * @see #setDataSource + * @see #setIncrementerName + * @see #setColumnName + */ + public AbstractIdentityColumnMaxValueIncrementer() { + } + + public AbstractIdentityColumnMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { + super(dataSource, incrementerName, columnName); + } + + + /** + * Specify whether to delete the entire range below the current maximum key value + * ({@code false} - the default), or the specifically generated values ({@code true}). + * The former mode will use a where range clause whereas the latter will use an in + * clause starting with the lowest value minus 1, just preserving the maximum value. + */ + public void setDeleteSpecificValues(boolean deleteSpecificValues) { + this.deleteSpecificValues = deleteSpecificValues; + } + + /** + * Return whether to delete the entire range below the current maximum key value + * ({@code false} - the default), or the specifically generated values ({@code true}). + */ + public boolean isDeleteSpecificValues() { + return this.deleteSpecificValues; + } + + + @Override + protected synchronized long getNextKey() throws DataAccessException { + if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { + /* + * Need to use straight JDBC code because we need to make sure that the insert and select + * are performed on the same connection (otherwise we can't be sure that @@identity + * returns the correct value) + */ + Connection con = DataSourceUtils.getConnection(getDataSource()); + Statement stmt = null; + try { + stmt = con.createStatement(); + DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); + this.valueCache = new long[getCacheSize()]; + this.nextValueIndex = 0; + for (int i = 0; i < getCacheSize(); i++) { + stmt.executeUpdate(getIncrementStatement()); + ResultSet rs = stmt.executeQuery(getIdentityStatement()); + try { + if (!rs.next()) { + throw new DataAccessResourceFailureException("Identity statement failed after inserting"); + } + this.valueCache[i] = rs.getLong(1); + } + finally { + JdbcUtils.closeResultSet(rs); + } + } + stmt.executeUpdate(getDeleteStatement(this.valueCache)); + } + catch (SQLException ex) { + throw new DataAccessResourceFailureException("Could not increment identity", ex); + } + finally { + JdbcUtils.closeStatement(stmt); + DataSourceUtils.releaseConnection(con, getDataSource()); + } + } + return this.valueCache[this.nextValueIndex++]; + } + + + /** + * Statement to use to increment the "sequence" value. + * @return the SQL statement to use + */ + protected abstract String getIncrementStatement(); + + /** + * Statement to use to obtain the current identity value. + * @return the SQL statement to use + */ + protected abstract String getIdentityStatement(); + + /** + * Statement to use to clean up "sequence" values. + * <p>The default implementation either deletes the entire range below + * the current maximum value, or the specifically generated values + * (starting with the lowest minus 1, just preserving the maximum value) + * - according to the {@link #isDeleteSpecificValues()} setting. + * @param values the currently generated key values + * (the number of values corresponds to {@link #getCacheSize()}) + * @return the SQL statement to use + */ + protected String getDeleteStatement(long[] values) { + StringBuilder sb = new StringBuilder(64); + sb.append("delete from ").append(getIncrementerName()).append(" where ").append(getColumnName()); + if (isDeleteSpecificValues()) { + sb.append(" in (").append(values[0] - 1); + for (int i = 0; i < values.length - 1; i++) { + sb.append(", ").append(values[i]); + } + sb.append(")"); + } + else { + long maxValue = values[values.length - 1]; + sb.append(" < ").append(maxValue); + } + return sb.toString(); + } + +} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractSequenceMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractSequenceMaxValueIncrementer.java index f8796fa2..9a295b1a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractSequenceMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractSequenceMaxValueIncrementer.java @@ -20,7 +20,6 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; - import javax.sql.DataSource; import org.springframework.dao.DataAccessException; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DerbyMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DerbyMaxValueIncrementer.java index 75b4e10d..6e0bfe1a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DerbyMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DerbyMaxValueIncrementer.java @@ -16,17 +16,8 @@ package org.springframework.jdbc.support.incrementer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import javax.sql.DataSource; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.JdbcUtils; - /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given Derby table * with the equivalent of an auto-increment column. Note: If you use this class, your Derby key @@ -62,7 +53,7 @@ import org.springframework.jdbc.support.JdbcUtils; * @author Juergen Hoeller * @since 2.5 */ -public class DerbyMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { +public class DerbyMaxValueIncrementer extends AbstractIdentityColumnMaxValueIncrementer { /** The default for dummy name */ private static final String DEFAULT_DUMMY_NAME = "dummy"; @@ -70,12 +61,6 @@ public class DerbyMaxValueIncrementer extends AbstractColumnMaxValueIncrementer /** The name of the dummy column used for inserts */ private String dummyName = DEFAULT_DUMMY_NAME; - /** The current cache of values */ - private long[] valueCache; - - /** The next id to serve from the value cache */ - private int nextValueIndex = -1; - /** * Default constructor for bean property style usage. @@ -126,45 +111,13 @@ public class DerbyMaxValueIncrementer extends AbstractColumnMaxValueIncrementer @Override - protected synchronized long getNextKey() throws DataAccessException { - if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { - /* - * Need to use straight JDBC code because we need to make sure that the insert and select - * are performed on the same connection (otherwise we can't be sure that last_insert_id() - * returned the correct value) - */ - Connection con = DataSourceUtils.getConnection(getDataSource()); - Statement stmt = null; - try { - stmt = con.createStatement(); - DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); - this.valueCache = new long[getCacheSize()]; - this.nextValueIndex = 0; - for (int i = 0; i < getCacheSize(); i++) { - stmt.executeUpdate("insert into " + getIncrementerName() + " (" + getDummyName() + ") values(null)"); - ResultSet rs = stmt.executeQuery("select IDENTITY_VAL_LOCAL() from " + getIncrementerName()); - try { - if (!rs.next()) { - throw new DataAccessResourceFailureException("IDENTITY_VAL_LOCAL() failed after executing an update"); - } - this.valueCache[i] = rs.getLong(1); - } - finally { - JdbcUtils.closeResultSet(rs); - } - } - long maxValue = this.valueCache[(this.valueCache.length - 1)]; - stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); - } - catch (SQLException ex) { - throw new DataAccessResourceFailureException("Could not obtain IDENTITY value", ex); - } - finally { - JdbcUtils.closeStatement(stmt); - DataSourceUtils.releaseConnection(con, getDataSource()); - } - } - return this.valueCache[this.nextValueIndex++]; + protected String getIncrementStatement() { + return "insert into " + getIncrementerName() + " (" + getDummyName() + ") values(null)"; + } + + @Override + protected String getIdentityStatement() { + return "select IDENTITY_VAL_LOCAL() from " + getIncrementerName(); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlMaxValueIncrementer.java index 279ba69b..11e757ec 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlMaxValueIncrementer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2014 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,18 +16,8 @@ package org.springframework.jdbc.support.incrementer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - import javax.sql.DataSource; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.JdbcUtils; - /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given HSQL table * with the equivalent of an auto-increment column. Note: If you use this class, your HSQL @@ -55,14 +45,7 @@ import org.springframework.jdbc.support.JdbcUtils; * @author Juergen Hoeller * @see HsqlSequenceMaxValueIncrementer */ -public class HsqlMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { - - /** The current cache of values */ - private long[] valueCache; - - /** The next id to serve from the value cache */ - private int nextValueIndex = -1; - +public class HsqlMaxValueIncrementer extends AbstractIdentityColumnMaxValueIncrementer { /** * Default constructor for bean property style usage. @@ -85,45 +68,13 @@ public class HsqlMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { @Override - protected synchronized long getNextKey() throws DataAccessException { - if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { - /* - * Need to use straight JDBC code because we need to make sure that the insert and select - * are performed on the same Connection. Otherwise we can't be sure that last_insert_id() - * returned the correct value. - */ - Connection con = DataSourceUtils.getConnection(getDataSource()); - Statement stmt = null; - try { - stmt = con.createStatement(); - DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); - this.valueCache = new long[getCacheSize()]; - this.nextValueIndex = 0; - for (int i = 0; i < getCacheSize(); i++) { - stmt.executeUpdate("insert into " + getIncrementerName() + " values(null)"); - ResultSet rs = stmt.executeQuery("select max(identity()) from " + getIncrementerName()); - try { - if (!rs.next()) { - throw new DataAccessResourceFailureException("identity() failed after executing an update"); - } - this.valueCache[i] = rs.getLong(1); - } - finally { - JdbcUtils.closeResultSet(rs); - } - } - long maxValue = this.valueCache[(this.valueCache.length - 1)]; - stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); - } - catch (SQLException ex) { - throw new DataAccessResourceFailureException("Could not obtain identity()", ex); - } - finally { - JdbcUtils.closeStatement(stmt); - DataSourceUtils.releaseConnection(con, getDataSource()); - } - } - return this.valueCache[this.nextValueIndex++]; + protected String getIncrementStatement() { + return "insert into " + getIncrementerName() + " values(null)"; + } + + @Override + protected String getIdentityStatement() { + return "select max(identity()) from " + getIncrementerName(); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLMaxValueIncrementer.java index 61090aec..2c3ad290 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLMaxValueIncrementer.java @@ -20,7 +20,6 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; - import javax.sql.DataSource; import org.springframework.dao.DataAccessException; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SqlServerMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SqlServerMaxValueIncrementer.java index a864fec5..c63eea58 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SqlServerMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SqlServerMaxValueIncrementer.java @@ -16,30 +16,21 @@ package org.springframework.jdbc.support.incrementer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import javax.sql.DataSource; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.JdbcUtils; - /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given SQL Server table - * with the equivalent of an auto-increment column. Note: If you use this class, your Derby key + * with the equivalent of an auto-increment column. Note: If you use this class, your table key * column should <i>NOT</i> be defined as an IDENTITY column, as the sequence table does the job. * - * <p>This class is inteded to be used with Microsoft SQL Server. + * <p>This class is intended to be used with Microsoft SQL Server. * * <p>The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * * <p>Example: * - * <pre class="code"> create table tab (id int not null primary key, text varchar(100)) + * <pre class="code">create table tab (id int not null primary key, text varchar(100)) * create table tab_sequence (id bigint identity) * insert into tab_sequence default values</pre> * @@ -58,16 +49,10 @@ import org.springframework.jdbc.support.JdbcUtils; * <p>Thanks to Preben Nilsson for the suggestion! * * @author Thomas Risberg + * @author Juergen Hoeller * @since 2.5.5 */ -public class SqlServerMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { - - /** The current cache of values */ - private long[] valueCache; - - /** The next id to serve from the value cache */ - private int nextValueIndex = -1; - +public class SqlServerMaxValueIncrementer extends AbstractIdentityColumnMaxValueIncrementer { /** * Default constructor for bean property style usage. @@ -90,45 +75,13 @@ public class SqlServerMaxValueIncrementer extends AbstractColumnMaxValueIncremen @Override - protected synchronized long getNextKey() throws DataAccessException { - if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { - /* - * Need to use straight JDBC code because we need to make sure that the insert and select - * are performed on the same connection (otherwise we can't be sure that @@identity - * returnes the correct value) - */ - Connection con = DataSourceUtils.getConnection(getDataSource()); - Statement stmt = null; - try { - stmt = con.createStatement(); - DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); - this.valueCache = new long[getCacheSize()]; - this.nextValueIndex = 0; - for (int i = 0; i < getCacheSize(); i++) { - stmt.executeUpdate("insert into " + getIncrementerName() + " default values"); - ResultSet rs = stmt.executeQuery("select @@identity"); - try { - if (!rs.next()) { - throw new DataAccessResourceFailureException("@@identity failed after executing an update"); - } - this.valueCache[i] = rs.getLong(1); - } - finally { - JdbcUtils.closeResultSet(rs); - } - } - long maxValue = this.valueCache[(this.valueCache.length - 1)]; - stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); - } - catch (SQLException ex) { - throw new DataAccessResourceFailureException("Could not increment identity", ex); - } - finally { - JdbcUtils.closeStatement(stmt); - DataSourceUtils.releaseConnection(con, getDataSource()); - } - } - return this.valueCache[this.nextValueIndex++]; + protected String getIncrementStatement() { + return "insert into " + getIncrementerName() + " default values"; + } + + @Override + protected String getIdentityStatement() { + return "select @@identity"; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java index 726fdb5f..8f6a6ec0 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.java @@ -31,7 +31,7 @@ import javax.sql.DataSource; * * <p>Example: * - * <pre class="code"> create table tab (id int not null primary key, text varchar(100)) + * <pre class="code">create table tab (id int not null primary key, text varchar(100)) * create table tab_sequence (id bigint identity) * insert into tab_sequence values(DEFAULT)</pre> * @@ -73,6 +73,7 @@ public class SybaseAnywhereMaxValueIncrementer extends SybaseMaxValueIncrementer super(dataSource, incrementerName, columnName); } + @Override protected String getIncrementStatement() { return "insert into " + getIncrementerName() + " values(DEFAULT)"; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java index 6c86bc94..5131b294 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.java @@ -16,20 +16,10 @@ package org.springframework.jdbc.support.incrementer; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import javax.sql.DataSource; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.support.JdbcUtils; - /** - * {@link DataFieldMaxValueIncrementer} that increments - * the maximum value of a given Sybase SQL Server table + * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given Sybase table * with the equivalent of an auto-increment column. Note: If you use this class, your table key * column should <i>NOT</i> be defined as an IDENTITY column, as the sequence table does the job. * @@ -40,7 +30,7 @@ import org.springframework.jdbc.support.JdbcUtils; * * <p>Example: * - * <pre class="code"> create table tab (id int not null primary key, text varchar(100)) + * <pre class="code">create table tab (id int not null primary key, text varchar(100)) * create table tab_sequence (id bigint identity) * insert into tab_sequence values()</pre> * @@ -59,16 +49,10 @@ import org.springframework.jdbc.support.JdbcUtils; * <p>Thanks to Yinwei Liu for the suggestion! * * @author Thomas Risberg + * @author Juergen Hoeller * @since 2.5.5 */ -public class SybaseMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { - - /** The current cache of values */ - private long[] valueCache; - - /** The next id to serve from the value cache */ - private int nextValueIndex = -1; - +public class SybaseMaxValueIncrementer extends AbstractIdentityColumnMaxValueIncrementer { /** * Default constructor for bean property style usage. @@ -91,53 +75,13 @@ public class SybaseMaxValueIncrementer extends AbstractColumnMaxValueIncrementer @Override - protected synchronized long getNextKey() throws DataAccessException { - if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { - /* - * Need to use straight JDBC code because we need to make sure that the insert and select - * are performed on the same connection (otherwise we can't be sure that @@identity - * returnes the correct value) - */ - Connection con = DataSourceUtils.getConnection(getDataSource()); - Statement stmt = null; - try { - stmt = con.createStatement(); - DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); - this.valueCache = new long[getCacheSize()]; - this.nextValueIndex = 0; - for (int i = 0; i < getCacheSize(); i++) { - stmt.executeUpdate(getIncrementStatement()); - ResultSet rs = stmt.executeQuery("select @@identity"); - try { - if (!rs.next()) { - throw new DataAccessResourceFailureException("@@identity failed after executing an update"); - } - this.valueCache[i] = rs.getLong(1); - } - finally { - JdbcUtils.closeResultSet(rs); - } - } - long maxValue = this.valueCache[(this.valueCache.length - 1)]; - stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); - } - catch (SQLException ex) { - throw new DataAccessResourceFailureException("Could not increment identity", ex); - } - finally { - JdbcUtils.closeStatement(stmt); - DataSourceUtils.releaseConnection(con, getDataSource()); - } - } - return this.valueCache[this.nextValueIndex++]; - } - - /** - * Statement to use to increment the "sequence" value. Can be overridden by subclasses. - * @return the SQL statement to use - */ protected String getIncrementStatement() { return "insert into " + getIncrementerName() + " values()"; } + @Override + protected String getIdentityStatement() { + return "select @@identity"; + } + } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/package-info.java index c6251e9b..93364ca2 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/package-info.java @@ -1,11 +1,7 @@ - /** - * * Provides a support framework for incrementing database table values * via sequences, with implementations for various databases. * * <p>Can be used independently, for example in custom JDBC access code. - * */ package org.springframework.jdbc.support.incrementer; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java index c1ae28cb..57aad967 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -36,6 +36,13 @@ import org.apache.commons.logging.LogFactory; * Invokes the direct accessor methods that {@code java.sql.ResultSet} * and {@code java.sql.PreparedStatement} offer. * + * <p>By default, incoming streams are going to be passed to the appropriate + * {@code setBinary/Ascii/CharacterStream} method on the JDBC driver's + * {@link PreparedStatement}. If the specified content length is negative, + * this handler will use the JDBC 4.0 variants of the set-stream methods + * without a length parameter; otherwise, it will pass the specified length + * on to the driver. + * * <p>This LobHandler should work for any JDBC driver that is JDBC compliant * in terms of the spec's suggestions regarding simple BLOB and CLOB handling. * This does not apply to Oracle 9i's drivers at all; as of Oracle 10g, @@ -248,7 +255,12 @@ public class DefaultLobHandler extends AbstractLobHandler { if (streamAsLob) { if (binaryStream != null) { - ps.setBlob(paramIndex, binaryStream, contentLength); + if (contentLength >= 0) { + ps.setBlob(paramIndex, binaryStream, contentLength); + } + else { + ps.setBlob(paramIndex, binaryStream); + } } else { ps.setBlob(paramIndex, (Blob) null); @@ -262,9 +274,12 @@ public class DefaultLobHandler extends AbstractLobHandler { ps.setBlob(paramIndex, (Blob) null); } } - else { + else if (contentLength >= 0) { ps.setBinaryStream(paramIndex, binaryStream, contentLength); } + else { + ps.setBinaryStream(paramIndex, binaryStream); + } if (logger.isDebugEnabled()) { logger.debug(binaryStream != null ? "Set binary stream for BLOB with length " + contentLength : "Set BLOB to null"); @@ -308,7 +323,13 @@ public class DefaultLobHandler extends AbstractLobHandler { if (streamAsLob) { if (asciiStream != null) { try { - ps.setClob(paramIndex, new InputStreamReader(asciiStream, "US-ASCII"), contentLength); + Reader reader = new InputStreamReader(asciiStream, "US-ASCII"); + if (contentLength >= 0) { + ps.setClob(paramIndex, reader, contentLength); + } + else { + ps.setClob(paramIndex, reader); + } } catch (UnsupportedEncodingException ex) { throw new SQLException("US-ASCII encoding not supported: " + ex); @@ -326,9 +347,12 @@ public class DefaultLobHandler extends AbstractLobHandler { ps.setClob(paramIndex, (Clob) null); } } - else { + else if (contentLength >= 0) { ps.setAsciiStream(paramIndex, asciiStream, contentLength); } + else { + ps.setAsciiStream(paramIndex, asciiStream); + } if (logger.isDebugEnabled()) { logger.debug(asciiStream != null ? "Set ASCII stream for CLOB with length " + contentLength : "Set CLOB to null"); @@ -342,7 +366,12 @@ public class DefaultLobHandler extends AbstractLobHandler { if (streamAsLob) { if (characterStream != null) { - ps.setClob(paramIndex, characterStream, contentLength); + if (contentLength >= 0) { + ps.setClob(paramIndex, characterStream, contentLength); + } + else { + ps.setClob(paramIndex, characterStream); + } } else { ps.setClob(paramIndex, (Clob) null); @@ -356,9 +385,12 @@ public class DefaultLobHandler extends AbstractLobHandler { ps.setClob(paramIndex, (Clob) null); } } - else { + else if (contentLength >= 0) { ps.setCharacterStream(paramIndex, characterStream, contentLength); } + else { + ps.setCharacterStream(paramIndex, characterStream); + } if (logger.isDebugEnabled()) { logger.debug(characterStream != null ? "Set character stream for CLOB with length " + contentLength : "Set CLOB to null"); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/package-info.java index 2991509b..ceea8ac1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/package-info.java @@ -1,12 +1,8 @@ - /** - * * Provides a stategy interface for Large OBject handling, * with implementations for various databases. * * <p>Can be used independently from jdbc.core and jdbc.object, * for example in custom JDBC access code. - * */ package org.springframework.jdbc.support.lob; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/CommonsDbcpNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/CommonsDbcpNativeJdbcExtractor.java index ee7d46f0..33045f9b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/CommonsDbcpNativeJdbcExtractor.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/CommonsDbcpNativeJdbcExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -29,7 +29,7 @@ import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for the - * Jakarta Commons DBCP connection pool, version 1.1 or higher. + * Apache Commons DBCP connection pool, version 1.1 or higher. * * <p>Returns the underlying native Connection, Statement, etc to application * code instead of DBCP's wrapper implementations. The returned JDBC classes diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java index 7a18b6d7..ca6d2ebb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -42,7 +42,7 @@ import java.sql.Statement; * * <p>When working with a simple connection pool that wraps Connections but not * Statements, a {@link SimpleNativeJdbcExtractor} is often sufficient. However, - * some pools (like Jakarta's Commons DBCP) wrap <i>all</i> JDBC objects that they + * some pools (like Apache's Commons DBCP) wrap <i>all</i> JDBC objects that they * return: Therefore, you need to use a specific {@code NativeJdbcExtractor} * (like {@link CommonsDbcpNativeJdbcExtractor}) with them. * diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java index fa0a1efc..5a6939c5 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -17,7 +17,7 @@ package org.springframework.jdbc.support.nativejdbc; /** - * Simple implementation of the {@link NativeJdbcExtractor} interface. + * A simple implementation of the {@link NativeJdbcExtractor} interface. * Assumes a pool that wraps Connection handles but not DatabaseMetaData: * In this case, the underlying native Connection can be retrieved by simply * calling {@code conHandle.getMetaData().getConnection()}. @@ -35,10 +35,9 @@ package org.springframework.jdbc.support.nativejdbc; * flags to "true". If none of the statement types is wrapped - or you solely need * Connection unwrapping in the first place -, the defaults are fine. * - * <p>SimpleNativeJdbcExtractor is a common choice for use with OracleLobHandler, - * which just needs Connection unwrapping via the - * {@link #getNativeConnectionFromStatement} method. This usage will work - * with almost any connection pool. + * <p>SimpleNativeJdbcExtractor is a common choice for use with OracleLobHandler, which + * just needs Connection unwrapping via the {@link #getNativeConnectionFromStatement} + * method. This usage will work with almost any connection pool. * * <p>For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping: * <ul> @@ -47,8 +46,8 @@ package org.springframework.jdbc.support.nativejdbc; * <li>Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx" * flags set to "true" for C3P0 (all JDBC Statement objects are wrapped, * but none of the wrappers allow for unwrapping). - * <li>Use a CommonsDbcpNativeJdbcExtractor for Jakarta Commons DBCP respectively - * a JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are wrapped, + * <li>Use a CommonsDbcpNativeJdbcExtractor for Apache Commons DBCP or a + * JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are wrapped, * but all of them can be extracted by casting to implementation classes). * </ul> * diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java index 1397cab0..172467cb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java @@ -1,11 +1,7 @@ - /** - * * Provides a mechanism for extracting native implementations of JDBC * interfaces from wrapper objects that got returned from connection pools. * * <p>Can be used independently, for example in custom JDBC access code. - * */ package org.springframework.jdbc.support.nativejdbc; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/package-info.java index 13f9784f..ecd758ee 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/package-info.java @@ -1,13 +1,9 @@ - /** - * * Support classes for the JDBC framework, used by the classes in the * jdbc.core and jdbc.object packages. Provides a translator from * SQLExceptions Spring's generic DataAccessExceptions. * * <p>Can be used independently, for example in custom JDBC access code, * or in JDBC-based O/R mapping layers. - * */ package org.springframework.jdbc.support; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java index 14d20761..98232269 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.InvalidResultSetAccessException; +import org.springframework.lang.UsesJava7; /** * The default implementation of Spring's {@link SqlRowSet} interface, wrapping a @@ -346,6 +347,27 @@ public class ResultSetWrappingSqlRowSet implements SqlRowSet { } /** + * @see java.sql.ResultSet#getNString(int) + */ + @Override + public String getNString(int columnIndex) throws InvalidResultSetAccessException { + try { + return this.resultSet.getNString(columnIndex); + } + catch (SQLException se) { + throw new InvalidResultSetAccessException(se); + } + } + + /** + * @see java.sql.ResultSet#getNString(String) + */ + @Override + public String getNString(String columnLabel) throws InvalidResultSetAccessException { + return getNString(findColumn(columnLabel)); + } + + /** * @see java.sql.ResultSet#getObject(int) */ @Override @@ -388,6 +410,28 @@ public class ResultSetWrappingSqlRowSet implements SqlRowSet { } /** + * @see java.sql.ResultSet#getObject(int, Class) + */ + @UsesJava7 + @Override + public <T> T getObject(int columnIndex, Class<T> type) throws InvalidResultSetAccessException { + try { + return this.resultSet.getObject(columnIndex, type); + } + catch (SQLException se) { + throw new InvalidResultSetAccessException(se); + } + } + + /** + * @see java.sql.ResultSet#getObject(String, Class) + */ + @Override + public <T> T getObject(String columnLabel, Class<T> type) throws InvalidResultSetAccessException { + return getObject(findColumn(columnLabel), type); + } + + /** * @see java.sql.ResultSet#getShort(int) */ @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSet.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSet.java index eca73405..ac434886 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSet.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSet.java @@ -235,6 +235,26 @@ public interface SqlRowSet extends Serializable { /** * Retrieve the value of the indicated column in the current row + * as a String (for NCHAR, NVARCHAR, LONGNVARCHAR columns). + * @param columnIndex the column index + * @return a String representing the column value + * @see java.sql.ResultSet#getNString(int) + * @since 4.1.3 + */ + String getNString(int columnIndex) throws InvalidResultSetAccessException; + + /** + * Retrieve the value of the indicated column in the current row + * as a String (for NCHAR, NVARCHAR, LONGNVARCHAR columns). + * @param columnLabel the column label + * @return a String representing the column value + * @see java.sql.ResultSet#getNString(String) + * @since 4.1.3 + */ + String getNString(String columnLabel) throws InvalidResultSetAccessException; + + /** + * Retrieve the value of the indicated column in the current row * as an Object. * @param columnIndex the column index * @return a Object representing the column value @@ -273,6 +293,28 @@ public interface SqlRowSet extends Serializable { /** * Retrieve the value of the indicated column in the current row + * as an Object. + * @param columnIndex the column index + * @param type the Java type to convert the designated column to + * @return a Object representing the column value + * @see java.sql.ResultSet#getObject(int) + * @since 4.1.3 + */ + <T> T getObject(int columnIndex, Class<T> type) throws InvalidResultSetAccessException; + + /** + * Retrieve the value of the indicated column in the current row + * as an Object. + * @param columnLabel the column label + * @param type the Java type to convert the designated column to + * @return a Object representing the column value + * @see java.sql.ResultSet#getObject(int) + * @since 4.1.3 + */ + <T> T getObject(String columnLabel, Class<T> type) throws InvalidResultSetAccessException; + + /** + * Retrieve the value of the indicated column in the current row * as a short. * @param columnIndex the column index * @return a short representing the column value diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/package-info.java index f9d3df63..b3d8f6c9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/package-info.java @@ -1,9 +1,5 @@ - /** - * * Provides a convenient holder for disconnected result sets. * Supported by JdbcTemplate, but can be used independently too. - * */ package org.springframework.jdbc.support.rowset; - diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java index 247e5368..b6c6a345 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -53,43 +53,55 @@ public class Jdbc4SqlXmlHandler implements SqlXmlHandler { @Override public String getXmlAsString(ResultSet rs, String columnName) throws SQLException { - return rs.getSQLXML(columnName).getString(); + SQLXML xmlObject = rs.getSQLXML(columnName); + return (xmlObject != null ? xmlObject.getString() : null); } @Override public String getXmlAsString(ResultSet rs, int columnIndex) throws SQLException { - return rs.getSQLXML(columnIndex).getString(); + SQLXML xmlObject = rs.getSQLXML(columnIndex); + return (xmlObject != null ? xmlObject.getString() : null); } @Override public InputStream getXmlAsBinaryStream(ResultSet rs, String columnName) throws SQLException { - return rs.getSQLXML(columnName).getBinaryStream(); + SQLXML xmlObject = rs.getSQLXML(columnName); + return (xmlObject != null ? xmlObject.getBinaryStream() : null); } @Override public InputStream getXmlAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException { - return rs.getSQLXML(columnIndex).getBinaryStream(); + SQLXML xmlObject = rs.getSQLXML(columnIndex); + return (xmlObject != null ? xmlObject.getBinaryStream() : null); } @Override public Reader getXmlAsCharacterStream(ResultSet rs, String columnName) throws SQLException { - return rs.getSQLXML(columnName).getCharacterStream(); + SQLXML xmlObject = rs.getSQLXML(columnName); + return (xmlObject != null ? xmlObject.getCharacterStream() : null); } @Override public Reader getXmlAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException { - return rs.getSQLXML(columnIndex).getCharacterStream(); + SQLXML xmlObject = rs.getSQLXML(columnIndex); + return (xmlObject != null ? xmlObject.getCharacterStream() : null); } @Override public Source getXmlAsSource(ResultSet rs, String columnName, Class<? extends Source> sourceClass) throws SQLException { SQLXML xmlObject = rs.getSQLXML(columnName); + if (xmlObject == null) { + return null; + } return (sourceClass != null ? xmlObject.getSource(sourceClass) : xmlObject.getSource(DOMSource.class)); } @Override public Source getXmlAsSource(ResultSet rs, int columnIndex, Class<? extends Source> sourceClass) throws SQLException { SQLXML xmlObject = rs.getSQLXML(columnIndex); + if (xmlObject == null) { + return null; + } return (sourceClass != null ? xmlObject.getSource(sourceClass) : xmlObject.getSource(DOMSource.class)); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlHandler.java index a7a59318..320a3bd9 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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.io.InputStream; import java.io.Reader; import java.sql.ResultSet; import java.sql.SQLException; - import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -113,7 +112,7 @@ public interface SqlXmlHandler { * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use - * @return the content as character stream + * @return the content as character stream, or {@code null} in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getCharacterStream @@ -127,7 +126,7 @@ public interface SqlXmlHandler { * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use - * @return the content as character stream + * @return the content as character stream, or {@code null} in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getCharacterStream @@ -142,7 +141,7 @@ public interface SqlXmlHandler { * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @param sourceClass the implementation class to be used - * @return the content as character stream + * @return the content as character stream, or {@code null} in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getSource @@ -157,7 +156,7 @@ public interface SqlXmlHandler { * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @param sourceClass the implementation class to be used - * @return the content as character stream + * @return the content as character stream, or {@code null} in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getSource diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlBinaryStreamProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlBinaryStreamProvider.java index 80241275..854fa2a6 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlBinaryStreamProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlBinaryStreamProvider.java @@ -16,8 +16,8 @@ package org.springframework.jdbc.support.xml; -import java.io.OutputStream; import java.io.IOException; +import java.io.OutputStream; /** * Interface defining handling involved with providing {@code OutputStream} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlCharacterStreamProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlCharacterStreamProvider.java index 9cb13d05..1ac6948a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlCharacterStreamProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlCharacterStreamProvider.java @@ -16,8 +16,8 @@ package org.springframework.jdbc.support.xml; -import java.io.Writer; import java.io.IOException; +import java.io.Writer; /** * Interface defining handling involved with providing {@code Writer} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/package-info.java index dd51bbee..a6e46df0 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/package-info.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/package-info.java @@ -1,8 +1,4 @@ - /** - * * Abstraction for handling fields of SQLXML data type. - * */ package org.springframework.jdbc.support.xml; - diff --git a/spring-jdbc/src/main/resources/META-INF/spring.schemas b/spring-jdbc/src/main/resources/META-INF/spring.schemas index 82513e67..59e1e687 100644 --- a/spring-jdbc/src/main/resources/META-INF/spring.schemas +++ b/spring-jdbc/src/main/resources/META-INF/spring.schemas @@ -2,4 +2,5 @@ http\://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd=org/springframew http\://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd=org/springframework/jdbc/config/spring-jdbc-3.1.xsd http\://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd=org/springframework/jdbc/config/spring-jdbc-3.2.xsd http\://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd=org/springframework/jdbc/config/spring-jdbc-4.0.xsd -http\://www.springframework.org/schema/jdbc/spring-jdbc.xsd=org/springframework/jdbc/config/spring-jdbc-4.0.xsd +http\://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd=org/springframework/jdbc/config/spring-jdbc-4.1.xsd +http\://www.springframework.org/schema/jdbc/spring-jdbc.xsd=org/springframework/jdbc/config/spring-jdbc-4.1.xsd diff --git a/spring-jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-4.1.xsd b/spring-jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-4.1.xsd new file mode 100644 index 00000000..60d39584 --- /dev/null +++ b/spring-jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-4.1.xsd @@ -0,0 +1,182 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<xsd:schema xmlns="http://www.springframework.org/schema/jdbc" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:tool="http://www.springframework.org/schema/tool" + targetNamespace="http://www.springframework.org/schema/jdbc" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> + + <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"/> + <xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.1.xsd"/> + + <xsd:element name="embedded-database"> + <xsd:annotation> + <xsd:documentation source="java:org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean"><![CDATA[ + Creates an embedded database instance and makes it available to other beans as a javax.sql.DataSource. + ]]></xsd:documentation> + <xsd:appinfo> + <tool:annotation> + <tool:exports type="javax.sql.DataSource"/> + </tool:annotation> + </xsd:appinfo> + </xsd:annotation> + <xsd:complexType> + <xsd:complexContent> + <xsd:extension base="beans:identifiedType"> + <xsd:sequence> + <xsd:element name="script" type="scriptType" minOccurs="0" maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + A SQL script to execute during embedded database initialization. + ]]></xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + <xsd:attribute name="type" type="databaseType" default="HSQL"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + The type of embedded database to create, such as HSQL, H2 or Derby. Defaults to HSQL. + ]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + </xsd:element> + + <xsd:element name="initialize-database"> + <xsd:annotation> + <xsd:documentation source="java:org.springframework.jdbc.datasource.init.DataSourceInitializer"><![CDATA[ + Initializes a database instance with SQL scripts provided in nested <script/> elements. + ]]></xsd:documentation> + </xsd:annotation> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="script" type="scriptType" minOccurs="1" maxOccurs="unbounded"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + A SQL script to execute during database initialization. + ]]></xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + <xsd:attribute name="data-source" type="xsd:string" default="dataSource"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + A reference to a data source that should be initialized. Defaults to "dataSource". + ]]></xsd:documentation> + <xsd:appinfo> + <tool:annotation kind="ref"/> + <tool:expected-type type="javax.sql.DataSource"/> + </xsd:appinfo> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="enabled" type="xsd:string" use="optional" default="true"> + <xsd:annotation> + <xsd:documentation> + Is this bean "enabled", meaning the scripts will be executed? + Defaults to true, but can be used to switch on and off the initialization depending on the environment. + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="ignore-failures" use="optional" default="NONE"> + <xsd:annotation> + <xsd:documentation> + Should failed SQL statements be ignored during initialization? + </xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="NONE"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Do not ignore failures (the default) + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="DROPS"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Ignore failed DROP statements + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="ALL"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Ignore all failures + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + </xsd:element> + + <xsd:complexType name="scriptType"> + <xsd:attribute name="location" type="xsd:string"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + The resource location of an SQL script to execute. Can be a single script location or a pattern (e.g. classpath:/com/foo/sql/*-data.sql). + ]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="encoding" type="xsd:string"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + The encoding for SQL scripts, if different from the platform encoding. + ]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="separator" type="xsd:string"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + The statement separator in the script (the default is to use ';' if it is present in the script, or '\n' otherwise). + ]]></xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="execution"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Indicate the timing of the execution of this script. Use INIT to execute on startup (as a bean initialization) and DESTROY to execute on shutdown (as a bean destruction callback). + ]]></xsd:documentation> + </xsd:annotation> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="INIT"/> + <xsd:enumeration value="DESTROY"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + </xsd:complexType> + + <xsd:simpleType name="databaseType"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="HSQL"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Hyper SQL Java Database Engine + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="H2"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + H2 Java Database Engine + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + <xsd:enumeration value="DERBY"> + <xsd:annotation> + <xsd:documentation><![CDATA[ + Derby Java Database Engine + ]]></xsd:documentation> + </xsd:annotation> + </xsd:enumeration> + </xsd:restriction> + </xsd:simpleType> + +</xsd:schema> diff --git a/spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml b/spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml index 15329647..3fe34efe 100644 --- a/spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml +++ b/spring-jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml @@ -248,4 +248,44 @@ </property> </bean> + <!-- http://help.sap.com/saphelp_hanaplatform/helpdata/en/20/a78d3275191014b41bae7c4a46d835/content.htm --> + <bean id="Hana" class="org.springframework.jdbc.support.SQLErrorCodes"> + <property name="databaseProductName"> + <value>SAP DB</value> + </property> + <property name="badSqlGrammarCodes"> + <value> + 257,259,260,261,262,263,264,267,268,269,270,271,272,273,275,276,277,278, + 278,279,280,281,282,283,284,285,286,288,289,290,294,295,296,297,299,308,309, + 313,315,316,318,319,320,321,322,323,324,328,329,330,333,335,336,337,338,340, + 343,350,351,352,362,368 + </value> + </property> + <property name="permissionDeniedCodes"> + <value>10,258</value> + </property> + <property name="duplicateKeyCodes"> + <value>301</value> + </property> + <property name="dataIntegrityViolationCodes"> + <value>461,462</value> + </property> + <property name="dataAccessResourceFailureCodes"> + <value>-813,-709,-708,1024,1025,1026,1027,1029,1030,1031</value> + </property> + <property name="invalidResultSetAccessCodes"> + <value>-11210,582,587,588,594</value> + </property> + <property name="cannotAcquireLockCodes"> + <value>131</value> + </property> + <property name="cannotSerializeTransactionCodes"> + <value>138,143</value> + </property> + <property name="deadlockLoserCodes"> + <value>133</value> + </property> + </bean> + + </beans> diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java index e6c9fdef..723707ad 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -37,8 +37,10 @@ import static org.junit.Assert.*; public class InitializeDatabaseIntegrationTests { private String enabled; + private ClassPathXmlApplicationContext context; + @Before public void init() { enabled = System.setProperty("ENABLED", "true"); @@ -48,7 +50,8 @@ public class InitializeDatabaseIntegrationTests { public void after() { if (enabled != null) { System.setProperty("ENABLED", enabled); - } else { + } + else { System.clearProperty("ENABLED"); } if (context != null) { @@ -56,6 +59,7 @@ public class InitializeDatabaseIntegrationTests { } } + @Test public void testCreateEmbeddedDatabase() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-config.xml"); @@ -107,13 +111,15 @@ public class InitializeDatabaseIntegrationTests { } private void assertCorrectSetup(DataSource dataSource) { - JdbcTemplate t = new JdbcTemplate(dataSource); - assertEquals(1, t.queryForInt("select count(*) from T_TEST")); + JdbcTemplate jt = new JdbcTemplate(dataSource); + assertEquals(1, jt.queryForObject("select count(*) from T_TEST", Integer.class).intValue()); } + public static class CacheData implements InitializingBean { private JdbcTemplate jdbcTemplate; + private List<Map<String,Object>> cache; public void setDataSource(DataSource dataSource) { @@ -128,7 +134,6 @@ public class InitializeDatabaseIntegrationTests { public void afterPropertiesSet() throws Exception { cache = jdbcTemplate.queryForList("SELECT * FROM T_TEST"); } - } } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java index 396418b9..79b5137e 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.java @@ -21,6 +21,7 @@ import javax.sql.DataSource; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java index 709ca312..fd9421a9 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.java @@ -16,13 +16,12 @@ package org.springframework.jdbc.core; -import static org.junit.Assert.assertEquals; - import java.util.List; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.beans.TypeMismatchException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.test.ConcretePerson; @@ -30,6 +29,8 @@ import org.springframework.jdbc.core.test.ExtendedPerson; import org.springframework.jdbc.core.test.Person; import org.springframework.jdbc.core.test.SpacePerson; +import static org.junit.Assert.*; + /** * @author Thomas Risberg * @author Juergen Hoeller diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java index f9963c11..721e08ca 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -26,13 +26,13 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.IncorrectResultSizeDataAccessException; import static org.junit.Assert.*; @@ -80,10 +80,10 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; given(this.resultSet.next()).willReturn(true, true, false); given(this.resultSet.getObject(1)).willReturn(11, 12); - List li = this.template.queryForList(sql); + List<Map<String, Object>> li = this.template.queryForList(sql); assertEquals("All rows returned", 2, li.size()); - assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); - assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue()); + assertEquals("First row is Integer", 11, ((Integer) li.get(0).get("age")).intValue()); + assertEquals("Second row is Integer", 12, ((Integer) li.get(1).get("age")).intValue()); verify(this.resultSet).close(); verify(this.statement).close(); } @@ -92,7 +92,7 @@ public class JdbcTemplateQueryTests { public void testQueryForListWithEmptyResult() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; given(this.resultSet.next()).willReturn(false); - List li = this.template.queryForList(sql); + List<Map<String, Object>> li = this.template.queryForList(sql); assertEquals("All rows returned", 0, li.size()); verify(this.resultSet).close(); verify(this.statement).close(); @@ -103,9 +103,9 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getObject(1)).willReturn(11); - List li = this.template.queryForList(sql); + List<Map<String, Object>> li = this.template.queryForList(sql); assertEquals("All rows returned", 1, li.size()); - assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); + assertEquals("First row is Integer", 11, ((Integer) li.get(0).get("age")).intValue()); verify(this.resultSet).close(); verify(this.statement).close(); } @@ -115,9 +115,9 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(11); - List li = this.template.queryForList(sql, Integer.class); + List<Integer> li = this.template.queryForList(sql, Integer.class); assertEquals("All rows returned", 1, li.size()); - assertEquals("Element is Integer", 11, ((Integer) li.get(0)).intValue()); + assertEquals("Element is Integer", 11, li.get(0).intValue()); verify(this.resultSet).close(); verify(this.statement).close(); } @@ -127,7 +127,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getObject(1)).willReturn(11); - Map map = this.template.queryForMap(sql); + Map<String, Object> map = this.template.queryForMap(sql); assertEquals("Wow is Integer", 11, ((Integer) map.get("age")).intValue()); verify(this.resultSet).close(); verify(this.statement).close(); @@ -177,7 +177,7 @@ public class JdbcTemplateQueryTests { public void testQueryForObjectWithBigInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; given(this.resultSet.next()).willReturn(true, false); - given(this.resultSet.getObject(1)).willReturn("22"); + given(this.resultSet.getObject(1, BigInteger.class)).willReturn(new BigInteger("22")); assertEquals(new BigInteger("22"), this.template.queryForObject(sql, BigInteger.class)); verify(this.resultSet).close(); verify(this.statement).close(); @@ -198,7 +198,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(22); - assertEquals(new Integer(22), this.template.queryForObject(sql, Integer.class)); + assertEquals(Integer.valueOf(22), this.template.queryForObject(sql, Integer.class)); verify(this.resultSet).close(); verify(this.statement).close(); } @@ -219,7 +219,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(22); - int i = this.template.queryForInt(sql); + int i = this.template.queryForObject(sql,Integer.class).intValue(); assertEquals("Return of an int", 22, i); verify(this.resultSet).close(); verify(this.statement).close(); @@ -230,7 +230,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getLong(1)).willReturn(87L); - long l = this.template.queryForLong(sql); + long l = this.template.queryForObject(sql, Long.class).longValue(); assertEquals("Return of a long", 87, l); verify(this.resultSet).close(); verify(this.statement).close(); @@ -249,10 +249,10 @@ public class JdbcTemplateQueryTests { private void doTestQueryForListWithArgs(String sql) throws Exception { given(this.resultSet.next()).willReturn(true, true, false); given(this.resultSet.getObject(1)).willReturn(11, 12); - List li = this.template.queryForList(sql, new Object[] {new Integer(3)}); + List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3}); assertEquals("All rows returned", 2, li.size()); - assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); - assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue()); + assertEquals("First row is Integer", 11, ((Integer) li.get(0).get("age")).intValue()); + assertEquals("Second row is Integer", 12, ((Integer) li.get(1).get("age")).intValue()); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); verify(this.preparedStatement).close(); @@ -262,7 +262,7 @@ public class JdbcTemplateQueryTests { public void testQueryForListWithArgsAndEmptyResult() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; given(this.resultSet.next()).willReturn(false); - List li = this.template.queryForList(sql, new Object[] {new Integer(3)}); + List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3}); assertEquals("All rows returned", 0, li.size()); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); @@ -274,9 +274,9 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getObject(1)).willReturn(11); - List li = this.template.queryForList(sql, new Object[] {new Integer(3)}); + List<Map<String, Object>> li = this.template.queryForList(sql, new Object[] {3}); assertEquals("All rows returned", 1, li.size()); - assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); + assertEquals("First row is Integer", 11, ((Integer) li.get(0).get("age")).intValue()); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); verify(this.preparedStatement).close(); @@ -287,9 +287,9 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(11); - List li = this.template.queryForList(sql, new Object[] {new Integer(3)}, Integer.class); + List<Integer> li = this.template.queryForList(sql, new Object[] {3}, Integer.class); assertEquals("All rows returned", 1, li.size()); - assertEquals("First row is Integer", 11, ((Integer) li.get(0)).intValue()); + assertEquals("First row is Integer", 11, li.get(0).intValue()); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); verify(this.preparedStatement).close(); @@ -300,7 +300,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getObject(1)).willReturn(11); - Map map = this.template.queryForMap(sql, new Object[] {new Integer(3)}); + Map<String, Object> map = this.template.queryForMap(sql, new Object[] {3}); assertEquals("Row is Integer", 11, ((Integer) map.get("age")).intValue()); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); @@ -312,7 +312,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(22); - Object o = this.template.queryForObject(sql, new Object[] {new Integer(3)}, new RowMapper<Integer>() { + Object o = this.template.queryForObject(sql, new Object[] {3}, new RowMapper<Integer>() { @Override public Integer mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getInt(1); @@ -329,7 +329,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(22); - Object o = this.template.queryForObject(sql, new Object[] {new Integer(3)}, Integer.class); + Object o = this.template.queryForObject(sql, new Object[] {3}, Integer.class); assertTrue("Correct result type", o instanceof Integer); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); @@ -341,7 +341,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getInt(1)).willReturn(22); - int i = this.template.queryForInt(sql, new Object[] {new Integer(3)}); + int i = this.template.queryForObject(sql, new Object[] {3}, Integer.class).intValue(); assertEquals("Return of an int", 22, i); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); @@ -353,7 +353,7 @@ public class JdbcTemplateQueryTests { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.getLong(1)).willReturn(87L); - long l = this.template.queryForLong(sql, new Object[] {new Integer(3)}); + long l = this.template.queryForObject(sql, new Object[] {3}, Long.class).longValue(); assertEquals("Return of a long", 87, l); verify(this.preparedStatement).setObject(1, 3); verify(this.resultSet).close(); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java index e8d9e19c..0008db79 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -31,13 +31,13 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.BadSqlGrammarException; @@ -1289,7 +1289,7 @@ public class JdbcTemplateTests { List<SqlParameter> params = new ArrayList<SqlParameter>(); params.add(new SqlOutParameter("a", 12)); - Map out = this.template.call(new CallableStatementCreator() { + Map<String, Object> out = this.template.call(new CallableStatementCreator() { @Override public CallableStatement createCallableStatement(Connection conn) throws SQLException { diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/RowMapperTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/RowMapperTests.java index c31d0809..9c3faf6d 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/RowMapperTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/RowMapperTests.java @@ -25,10 +25,10 @@ import java.sql.Types; import java.util.List; import junit.framework.TestCase; - import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; import org.springframework.tests.sample.beans.TestBean; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java index 88f1e510..1c7cb2e3 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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,11 +38,13 @@ public class StatementCreatorUtilsTests { private PreparedStatement preparedStatement; + @Before public void setUp() { preparedStatement = mock(PreparedStatement.class); } + @Test public void testSetParameterValueWithNullAndType() throws SQLException { StatementCreatorUtils.setParameterValue(preparedStatement, 1, Types.VARCHAR, null, null); @@ -262,4 +264,21 @@ public class StatementCreatorUtilsTests { verify(preparedStatement).setTimestamp(1, new java.sql.Timestamp(cal.getTime().getTime()), cal); } + @Test // SPR-8571 + public void testSetParameterValueWithStringAndVendorSpecificType() throws SQLException { + Connection con = mock(Connection.class); + DatabaseMetaData dbmd = mock(DatabaseMetaData.class); + given(preparedStatement.getConnection()).willReturn(con); + given(dbmd.getDatabaseProductName()).willReturn("Oracle"); + given(con.getMetaData()).willReturn(dbmd); + StatementCreatorUtils.setParameterValue(preparedStatement, 1, Types.OTHER, null, "test"); + verify(preparedStatement).setString(1, "test"); + } + + @Test // SPR-8571 + public void testSetParameterValueWithNullAndVendorSpecificType() throws SQLException { + StatementCreatorUtils.setParameterValue(preparedStatement, 1, Types.OTHER, null, null); + verify(preparedStatement).setNull(1, Types.NULL); + } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSourceTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSourceTests.java index 15b0e219..ce4860fd 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSourceTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSourceTests.java @@ -19,11 +19,12 @@ package org.springframework.jdbc.core.namedparam; import java.sql.Types; import java.util.Arrays; -import static org.junit.Assert.*; import org.junit.Test; import org.springframework.tests.sample.beans.TestBean; +import static org.junit.Assert.*; + /** * @author Rick Evans * @author Juergen Hoeller diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSourceTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSourceTests.java index d7a76132..0676f608 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSourceTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSourceTests.java @@ -16,11 +16,12 @@ package org.springframework.jdbc.core.namedparam; -import static org.junit.Assert.assertEquals; import org.junit.Test; import org.springframework.jdbc.core.SqlParameterValue; +import static org.junit.Assert.*; + /** * @author Rick Evans * @author Arjen Poutsma diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplateTests.java index a8c27275..56a3bbf4 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplateTests.java @@ -27,13 +27,13 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.DataAccessException; import org.springframework.jdbc.Customer; import org.springframework.jdbc.core.JdbcOperations; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java index 271caa93..d4d2cb61 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,12 +27,12 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.core.RowMapper; import static org.junit.Assert.*; @@ -91,9 +91,9 @@ public class NamedParameterQueryTests { assertEquals("All rows returned", 2, li.size()); assertEquals("First row is Integer", 11, - ((Integer) ((Map) li.get(0)).get("age")).intValue()); + ((Integer) li.get(0).get("age")).intValue()); assertEquals("Second row is Integer", 12, - ((Integer) ((Map) li.get(1)).get("age")).intValue()); + ((Integer) li.get(1).get("age")).intValue()); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?"); verify(preparedStatement).setObject(1, 3); @@ -126,7 +126,7 @@ public class NamedParameterQueryTests { assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, - ((Integer) ((Map) li.get(0)).get("age")).intValue()); + ((Integer) li.get(0).get("age")).intValue()); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?"); verify(preparedStatement).setObject(1, 3); } @@ -157,7 +157,7 @@ public class NamedParameterQueryTests { MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", 3); - Map map = template.queryForMap("SELECT AGE FROM CUSTMR WHERE ID < :id", parms); + Map<String, Object> map = template.queryForMap("SELECT AGE FROM CUSTMR WHERE ID < :id", parms); assertEquals("Row is Integer", 11, ((Integer) map.get("age")).intValue()); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?"); @@ -262,7 +262,7 @@ public class NamedParameterQueryTests { MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", 3); - int i = template.queryForInt("SELECT AGE FROM CUSTMR WHERE ID = :id", parms); + int i = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", parms, Integer.class).intValue(); assertEquals("Return of an int", 22, i); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?"); @@ -278,7 +278,7 @@ public class NamedParameterQueryTests { BeanPropertySqlParameterSource parms = new BeanPropertySqlParameterSource( new ParameterBean(3)); - long l = template.queryForLong("SELECT AGE FROM CUSTMR WHERE ID = :id", parms); + long l = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", parms, Long.class).longValue(); assertEquals("Return of a long", 87, l); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?"); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/CallMetaDataContextTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/CallMetaDataContextTests.java index 22498510..c4a497a4 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/CallMetaDataContextTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/CallMetaDataContextTests.java @@ -6,12 +6,12 @@ import java.sql.Types; import java.util.ArrayList; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapperTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapperTests.java index 232c3843..11f5af60 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapperTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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,21 +16,23 @@ package org.springframework.jdbc.core.simple; -import static org.junit.Assert.assertEquals; - import java.util.List; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.AbstractRowMapperTests; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.Person; +import static org.junit.Assert.*; + /** * @author Thomas Risberg */ +@SuppressWarnings("deprecation") public class ParameterizedBeanPropertyRowMapperTests extends AbstractRowMapperTests { @Rule diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java index 0559f34b..b11962c2 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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,13 +22,13 @@ import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.SqlOutParameter; @@ -103,8 +103,7 @@ public class SimpleJdbcCallTests { adder.declareParameters( new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), - new SqlOutParameter("newid", - Types.INTEGER)); + new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, new MapSqlParameterSource(). addValue("amount", 1103). addValue("custid", 3)); @@ -120,8 +119,7 @@ public class SimpleJdbcCallTests { adder.declareParameters( new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), - new SqlOutParameter("newid", - Types.INTEGER)); + new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, 1103, 3); assertEquals(4, newId.intValue()); verifyAddInvoiceWithoutMetaData(false); @@ -193,7 +191,8 @@ public class SimpleJdbcCallTests { } - @Test public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception { + @Test + public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception { initializeAddInvoiceWithMetaData(true); SimpleJdbcCall adder = new SimpleJdbcCall(dataSource).withFunctionName("add_invoice"); Number newId = adder.executeFunction(Number.class, 1103, 3); @@ -203,8 +202,7 @@ public class SimpleJdbcCallTests { } - private void initializeAddInvoiceWithoutMetaData(boolean isFunction) - throws SQLException { + private void initializeAddInvoiceWithoutMetaData(boolean isFunction) throws SQLException { given(databaseMetaData.getDatabaseProductName()).willReturn("MyDB"); given(databaseMetaData.getUserName()).willReturn("me"); given(databaseMetaData.storesLowerCaseIdentifiers()).willReturn(true); @@ -281,6 +279,6 @@ public class SimpleJdbcCallTests { verify(callableStatement).close(); verify(proceduresResultSet).close(); verify(procedureColumnsResultSet).close(); + } } -} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.java index 9d76aeeb..2bd32f1a 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.java @@ -20,7 +20,6 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.util.HashMap; - import javax.sql.DataSource; import org.junit.After; @@ -28,6 +27,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.InvalidDataAccessApiUsageException; import static org.mockito.BDDMockito.*; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplateTests.java index 8c5a2024..38dcf4be 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplateTests.java @@ -28,11 +28,11 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/TableMetaDataContextTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/TableMetaDataContextTests.java index 968883fd..16b43d68 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/TableMetaDataContextTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/TableMetaDataContextTests.java @@ -23,11 +23,11 @@ import java.sql.Types; import java.util.ArrayList; import java.util.Date; import java.util.List; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.core.metadata.TableMetaDataContext; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReaderTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReaderTests.java index 6e5779c2..bc7dfa59 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReaderTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReaderTests.java @@ -19,10 +19,10 @@ package org.springframework.jdbc.core.support; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.tests.sample.beans.TestBean; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcDaoSupportTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcDaoSupportTests.java index 45e11b3c..5338428b 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcDaoSupportTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcDaoSupportTests.java @@ -18,10 +18,10 @@ package org.springframework.jdbc.core.support; import java.util.ArrayList; import java.util.List; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.jdbc.core.JdbcTemplate; import static org.junit.Assert.*; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/LobSupportTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/LobSupportTests.java index a243d59b..5587af0a 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/LobSupportTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/LobSupportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -24,6 +24,7 @@ import java.sql.SQLException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.LobRetrievalFailureException; @@ -65,7 +66,7 @@ public class LobSupportTests { } }; - assertEquals(new Integer(3), psc.doInPreparedStatement(ps)); + assertEquals(Integer.valueOf(3), psc.doInPreparedStatement(ps)); assertTrue(svc.b); verify(creator).close(); verify(handler).getLobCreator(); @@ -75,7 +76,7 @@ public class LobSupportTests { @Test public void testAbstractLobStreamingResultSetExtractorNoRows() throws SQLException { ResultSet rset = mock(ResultSet.class); - AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); + AbstractLobStreamingResultSetExtractor<Void> lobRse = getResultSetExtractor(false); thrown.expect(IncorrectResultSizeDataAccessException.class); try { lobRse.extractData(rset); @@ -89,7 +90,7 @@ public class LobSupportTests { public void testAbstractLobStreamingResultSetExtractorOneRow() throws SQLException { ResultSet rset = mock(ResultSet.class); given(rset.next()).willReturn(true, false); - AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); + AbstractLobStreamingResultSetExtractor<Void> lobRse = getResultSetExtractor(false); lobRse.extractData(rset); verify(rset).clearWarnings(); } @@ -99,7 +100,7 @@ public class LobSupportTests { throws SQLException { ResultSet rset = mock(ResultSet.class); given(rset.next()).willReturn(true, true, false); - AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); + AbstractLobStreamingResultSetExtractor<Void> lobRse = getResultSetExtractor(false); thrown.expect(IncorrectResultSizeDataAccessException.class); try { lobRse.extractData(rset); @@ -114,13 +115,13 @@ public class LobSupportTests { throws SQLException { ResultSet rset = mock(ResultSet.class); given(rset.next()).willReturn(true); - AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(true); + AbstractLobStreamingResultSetExtractor<Void> lobRse = getResultSetExtractor(true); thrown.expect(LobRetrievalFailureException.class); lobRse.extractData(rset); } - private AbstractLobStreamingResultSetExtractor getResultSetExtractor(final boolean ex) { - AbstractLobStreamingResultSetExtractor lobRse = new AbstractLobStreamingResultSetExtractor() { + private AbstractLobStreamingResultSetExtractor<Void> getResultSetExtractor(final boolean ex) { + AbstractLobStreamingResultSetExtractor<Void> lobRse = new AbstractLobStreamingResultSetExtractor<Void>() { @Override protected void streamData(ResultSet rs) throws SQLException, IOException { diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlLobValueTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlLobValueTests.java index d0003d4f..4766b9d1 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlLobValueTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/support/SqlLobValueTests.java @@ -29,6 +29,7 @@ import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.MockitoAnnotations; + import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java index 4563a2b1..c5247749 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.java @@ -21,7 +21,6 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import javax.transaction.RollbackException; import javax.transaction.Status; @@ -33,6 +32,7 @@ import javax.transaction.UserTransaction; import org.junit.After; import org.junit.Before; import org.junit.Test; + import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.jdbc.datasource.lookup.BeanFactoryDataSourceLookup; import org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java index 3c29aa3a..e4ecd2fc 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,13 +21,13 @@ import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; - import javax.sql.DataSource; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; + import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.UncategorizedSQLException; import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; @@ -57,9 +57,12 @@ import static org.mockito.BDDMockito.*; public class DataSourceTransactionManagerTests { private Connection con; + private DataSource ds; + private DataSourceTransactionManager tm; + @Before public void setUp() throws Exception { con = mock(Connection.class); @@ -76,6 +79,7 @@ public class DataSourceTransactionManagerTests { assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); } + @Test public void testTransactionCommitWithAutoCommitTrue() throws Exception { doTestTransactionCommitRestoringAutoCommit(true, false, false); @@ -1290,6 +1294,7 @@ public class DataSourceTransactionManagerTests { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); verify(con).rollback(sp); + verify(con).releaseSavepoint(sp); verify(con).commit(); verify(con).isReadOnly(); verify(con).close(); @@ -1395,14 +1400,19 @@ public class DataSourceTransactionManagerTests { verify(con).close(); } + private static class TestTransactionSynchronization implements TransactionSynchronization { private DataSource dataSource; + private int status; public boolean beforeCommitCalled; + public boolean beforeCompletionCalled; + public boolean afterCommitCalled; + public boolean afterCompletionCalled; public TestTransactionSynchronization(DataSource dataSource, int status) { diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DelegatingDataSourceTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DelegatingDataSourceTests.java index 5782fc2e..6d3cf506 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DelegatingDataSourceTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DelegatingDataSourceTests.java @@ -19,7 +19,6 @@ package org.springframework.jdbc.datasource; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.sql.Connection; - import javax.sql.DataSource; import org.junit.Test; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapterTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapterTests.java index 0a9f8b7d..ad60d5da 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapterTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapterTests.java @@ -18,7 +18,6 @@ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; - import javax.sql.DataSource; import org.junit.Test; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilderTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilderTests.java index f3a43be8..3d430064 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilderTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilderTests.java @@ -17,6 +17,7 @@ package org.springframework.jdbc.datasource.embedded; import org.junit.Test; + import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.CannotReadScriptException; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java index 8d9bf392..76bc8547 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.java @@ -19,6 +19,7 @@ package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; import org.junit.Test; + import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.core.io.Resource; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java index 5be6e26d..18f62afb 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabaseInitializationTests.java @@ -18,6 +18,7 @@ package org.springframework.jdbc.datasource.init; import org.junit.After; import org.junit.Before; + import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.core.io.Resource; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java index 82d8acfe..38bd4a7c 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/AbstractDatabasePopulatorTests.java @@ -20,6 +20,7 @@ import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; + import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -41,7 +42,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni @Test - public void buildWithCommentsAndFailedDrop() throws Exception { + public void scriptWithSingleLineCommentsAndFailedDrop() throws Exception { databasePopulator.addScript(resource("db-schema-failed-drop-comments.sql")); databasePopulator.addScript(resource("db-test-data.sql")); databasePopulator.setIgnoreFailedDrops(true); @@ -50,7 +51,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithNormalEscapedLiteral() throws Exception { + public void scriptWithStandardEscapedLiteral() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-escaped-literal.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); @@ -58,7 +59,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMySQLEscapedLiteral() throws Exception { + public void scriptWithMySqlEscapedLiteral() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-mysql-escaped-literal.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); @@ -66,7 +67,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMultipleStatements() throws Exception { + public void scriptWithMultipleStatements() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-multiple.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); @@ -77,7 +78,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMultipleStatementsLongSeparator() throws Exception { + public void scriptWithMultipleStatementsAndLongSeparator() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-endings.sql")); databasePopulator.setSeparator("@@"); @@ -89,7 +90,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMultipleStatementsWhitespaceSeparator() throws Exception { + public void scriptWithMultipleStatementsAndWhitespaceSeparator() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-whitespace.sql")); databasePopulator.setSeparator("/\n"); @@ -101,7 +102,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMultipleStatementsNewlineSeparator() throws Exception { + public void scriptWithMultipleStatementsAndNewlineSeparator() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-newline.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); @@ -112,7 +113,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithMultipleStatementsMultipleNewlineSeparator() throws Exception { + public void scriptWithMultipleStatementsAndMultipleNewlineSeparator() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-multi-newline.sql")); databasePopulator.setSeparator("\n\n"); @@ -144,7 +145,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni databasePopulator.setSeparator(ScriptUtils.EOF_STATEMENT_SEPARATOR); databasePopulator.addScript(resource("drop-users-schema.sql")); databasePopulator.addScript(resource("users-schema-without-separator.sql")); - databasePopulator.addScript(resource("users-data.sql")); + databasePopulator.addScript(resource("users-data-without-separator.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); assertUsersDatabaseCreated("Brannen"); @@ -159,7 +160,7 @@ public abstract class AbstractDatabasePopulatorTests extends AbstractDatabaseIni } @Test - public void buildWithSelectStatements() throws Exception { + public void scriptWithSelectStatements() throws Exception { databasePopulator.addScript(defaultSchema()); databasePopulator.addScript(resource("db-test-data-select.sql")); DatabasePopulatorUtils.execute(databasePopulator, db); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java new file mode 100644 index 00000000..0dcaf482 --- /dev/null +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulatorTests.java @@ -0,0 +1,107 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jdbc.datasource.init; + +import org.junit.Test; +import org.mockito.Mockito; + +import org.springframework.core.io.Resource; + +import static org.junit.Assert.*; + +/** + * Unit tests for {@link ResourceDatabasePopulator}. + * + * @author Sam Brannen + * @since 4.1 + * @see AbstractDatabasePopulatorTests + */ +public class ResourceDatabasePopulatorTests { + + private static final Resource script1 = Mockito.mock(Resource.class); + private static final Resource script2 = Mockito.mock(Resource.class); + private static final Resource script3 = Mockito.mock(Resource.class); + + + @Test(expected = IllegalArgumentException.class) + public void constructWithNullResource() { + new ResourceDatabasePopulator((Resource) null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructWithNullResourceArray() { + new ResourceDatabasePopulator((Resource[]) null); + } + + @Test + public void constructWithResource() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(script1); + assertEquals(1, databasePopulator.getScripts().size()); + } + + @Test + public void constructWithMultipleResources() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(script1, script2); + assertEquals(2, databasePopulator.getScripts().size()); + } + + @Test + public void constructWithMultipleResourcesAndThenAddScript() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(script1, script2); + assertEquals(2, databasePopulator.getScripts().size()); + + databasePopulator.addScript(script3); + assertEquals(3, databasePopulator.getScripts().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void addScriptsWithNullResource() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScripts((Resource) null); + } + + @Test(expected = IllegalArgumentException.class) + public void addScriptsWithNullResourceArray() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.addScripts((Resource[]) null); + } + + @Test(expected = IllegalArgumentException.class) + public void setScriptsWithNullResource() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.setScripts((Resource) null); + } + + @Test(expected = IllegalArgumentException.class) + public void setScriptsWithNullResourceArray() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + databasePopulator.setScripts((Resource[]) null); + } + + @Test + public void setScriptsAndThenAddScript() { + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); + assertEquals(0, databasePopulator.getScripts().size()); + + databasePopulator.setScripts(script1, script2); + assertEquals(2, databasePopulator.getScripts().size()); + + databasePopulator.addScript(script3); + assertEquals(3, databasePopulator.getScripts().size()); + } + +} diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java index 76f03a93..7a34a9db 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsIntegrationTests.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,6 +19,7 @@ package org.springframework.jdbc.datasource.init; import java.sql.SQLException; import org.junit.Test; + import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import static org.springframework.jdbc.datasource.init.ScriptUtils.*; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java index 6df2eb17..224a22b7 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/init/ScriptUtilsUnitTests.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import org.junit.Test; + import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.support.EncodedResource; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookupTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookupTests.java index ec2e2b4d..a1b19afa 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookupTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookupTests.java @@ -19,6 +19,7 @@ package org.springframework.jdbc.datasource.lookup; import javax.sql.DataSource; import org.junit.Test; + import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanNotOfRequiredTypeException; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookupTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookupTests.java index 49677564..11ae5684 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookupTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookupTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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,13 +16,13 @@ package org.springframework.jdbc.datasource.lookup; -import static org.junit.Assert.*; - import javax.naming.NamingException; import javax.sql.DataSource; import org.junit.Test; +import static org.junit.Assert.*; + /** * @author Rick Evans * @author Chris Beams @@ -36,10 +36,9 @@ public final class JndiDataSourceLookupTests { final DataSource expectedDataSource = new StubDataSource(); JndiDataSourceLookup lookup = new JndiDataSourceLookup() { @Override - @SuppressWarnings("unchecked") - protected Object lookup(String jndiName, Class requiredType) { + protected <T> T lookup(String jndiName, Class<T> requiredType) { assertEquals(DATA_SOURCE_NAME, jndiName); - return expectedDataSource; + return requiredType.cast(expectedDataSource); } }; DataSource dataSource = lookup.getDataSource(DATA_SOURCE_NAME); @@ -51,8 +50,7 @@ public final class JndiDataSourceLookupTests { public void testNoDataSourceAtJndiLocation() throws Exception { JndiDataSourceLookup lookup = new JndiDataSourceLookup() { @Override - @SuppressWarnings("unchecked") - protected Object lookup(String jndiName, Class requiredType) throws NamingException { + protected <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException { assertEquals(DATA_SOURCE_NAME, jndiName); throw new NamingException(); } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookupTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookupTests.java index 2c91098e..ed5bea85 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookupTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookupTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 the original author or authors. + * Copyright 2002-2014 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,15 +16,14 @@ package org.springframework.jdbc.datasource.lookup; -import static org.junit.Assert.*; - import java.util.HashMap; import java.util.Map; - import javax.sql.DataSource; import org.junit.Test; +import static org.junit.Assert.*; + /** * @author Rick Evans * @author Chris Beams @@ -37,7 +36,7 @@ public final class MapDataSourceLookupTests { @SuppressWarnings("unchecked") @Test(expected=UnsupportedOperationException.class) public void testGetDataSourcesReturnsUnmodifiableMap() throws Exception { - MapDataSourceLookup lookup = new MapDataSourceLookup(new HashMap()); + MapDataSourceLookup lookup = new MapDataSourceLookup(new HashMap<String, DataSource>()); Map dataSources = lookup.getDataSources(); dataSources.put("", ""); } @@ -84,7 +83,7 @@ public final class MapDataSourceLookupTests { @SuppressWarnings("unchecked") @Test(expected=ClassCastException.class) public void testGetDataSourceWhereSuppliedMapHasNonDataSourceTypeUnderSpecifiedKey() throws Exception { - Map dataSources = new HashMap(); + Map dataSources = new HashMap<String, DataSource>(); dataSources.put(DATA_SOURCE_NAME, new Object()); MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.setDataSources(dataSources); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/BatchSqlUpdateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/BatchSqlUpdateTests.java index e0352b94..1c2a0317 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/BatchSqlUpdateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/BatchSqlUpdateTests.java @@ -1,17 +1,17 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. You may obtain a copy of - * the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.springframework.jdbc.object; @@ -20,10 +20,10 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.Types; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.jdbc.core.SqlParameter; import static org.junit.Assert.*; @@ -100,8 +100,8 @@ public class BatchSqlUpdateTests { update.reset(); assertEquals(0, update.getRowsAffected().length); - verify(preparedStatement).setObject(1, new Integer(ids[0]), Types.INTEGER); - verify(preparedStatement).setObject(1, new Integer(ids[1]), Types.INTEGER); + verify(preparedStatement).setObject(1, ids[0], Types.INTEGER); + verify(preparedStatement).setObject(1, ids[1], Types.INTEGER); verify(preparedStatement, times(2)).addBatch(); verify(preparedStatement).close(); } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/CustomerMapper.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/CustomerMapper.java index 9a1e61d9..b4af1a4e 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/CustomerMapper.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/CustomerMapper.java @@ -1,11 +1,11 @@ package org.springframework.jdbc.object; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.Customer; - import java.sql.ResultSet; import java.sql.SQLException; +import org.springframework.jdbc.Customer; +import org.springframework.jdbc.core.RowMapper; + public class CustomerMapper implements RowMapper<Customer> { private static final String[] COLUMN_NAMES = new String[] {"id", "forename"}; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.java index b43b6895..ed32b628 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,11 +25,11 @@ import java.sql.Types; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Test; + import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -73,17 +73,17 @@ public class GenericSqlQueryTests { @Test public void testPlaceHoldersCustomerQuery() throws SQLException { - SqlQuery query = (SqlQuery) beanFactory.getBean("queryWithPlaceHolders"); + SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithPlaceHolders"); doTestCustomerQuery(query, false); } @Test public void testNamedParameterCustomerQuery() throws SQLException { - SqlQuery query = (SqlQuery) beanFactory.getBean("queryWithNamedParameters"); + SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithNamedParameters"); doTestCustomerQuery(query, true); } - private void doTestCustomerQuery(SqlQuery query, boolean namedParameters) throws SQLException { + private void doTestCustomerQuery(SqlQuery<?> query, boolean namedParameters) throws SQLException { given(resultSet.next()).willReturn(true); given(resultSet.getInt("id")).willReturn(1); given(resultSet.getString("forename")).willReturn("rod"); @@ -91,15 +91,15 @@ public class GenericSqlQueryTests { given(preparedStatement.executeQuery()).willReturn(resultSet); given(connection.prepareStatement(SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED)).willReturn(preparedStatement); - List queryResults; + List<?> queryResults; if (namedParameters) { Map<String, Object> params = new HashMap<String, Object>(2); - params.put("id", new Integer(1)); + params.put("id", 1); params.put("country", "UK"); queryResults = query.executeByNamedParam(params); } else { - Object[] params = new Object[] {new Integer(1), "UK"}; + Object[] params = new Object[] {1, "UK"}; queryResults = query.execute(params); } assertTrue("Customer was returned correctly", queryResults.size() == 1); @@ -108,7 +108,7 @@ public class GenericSqlQueryTests { assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); verify(resultSet).close(); - verify(preparedStatement).setObject(1, new Integer(1), Types.INTEGER); + verify(preparedStatement).setObject(1, 1, Types.INTEGER); verify(preparedStatement).setString(2, "UK"); verify(preparedStatement).close(); } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericStoredProcedureTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericStoredProcedureTests.java index c7260f2b..7471cf0a 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericStoredProcedureTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericStoredProcedureTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,15 +21,13 @@ import java.sql.Connection; import java.sql.Types; import java.util.HashMap; import java.util.Map; - import javax.sql.DataSource; -import org.apache.commons.logging.LogFactory; import org.junit.Test; + import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; -import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.TestDataSourceWrapper; import static org.junit.Assert.*; @@ -40,8 +38,6 @@ import static org.mockito.BDDMockito.*; */ public class GenericStoredProcedureTests { - private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); - @Test public void testAddInvoices() throws Exception { DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); @@ -56,7 +52,7 @@ public class GenericStoredProcedureTests { given(callableStatement.execute()).willReturn(false); given(callableStatement.getUpdateCount()).willReturn(-1); - given(callableStatement.getObject(3)).willReturn(new Integer(4)); + given(callableStatement.getObject(3)).willReturn(4); given(connection.prepareCall("{call " + "add_invoice" + "(?, ?, ?)}")).willReturn(callableStatement); @@ -64,12 +60,12 @@ public class GenericStoredProcedureTests { Map<String, Object> in = new HashMap<String, Object>(2); in.put("amount", 1106); in.put("custid", 3); - Map out = adder.execute(in); + Map<String, Object> out = adder.execute(in); Integer id = (Integer) out.get("newid"); assertEquals(4, id.intValue()); - verify(callableStatement).setObject(1, new Integer(1106), Types.INTEGER); - verify(callableStatement).setObject(2, new Integer(3), Types.INTEGER); + verify(callableStatement).setObject(1, 1106, Types.INTEGER); + verify(callableStatement).setObject(2, 3, Types.INTEGER); verify(callableStatement).registerOutParameter(3, Types.INTEGER); verify(callableStatement).close(); } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/RdbmsOperationTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/RdbmsOperationTests.java index d2d0cd82..d0ff6c19 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/RdbmsOperationTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/RdbmsOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -19,9 +19,6 @@ package org.springframework.jdbc.object; import java.sql.Types; import java.util.HashMap; import java.util.Map; -import java.util.List; -import java.util.ArrayList; - import javax.sql.DataSource; import junit.framework.TestCase; @@ -96,7 +93,7 @@ public class RdbmsOperationTests extends TestCase { operation.setSql("select * from mytable"); operation.setTypes(new int[] { Types.INTEGER }); try { - operation.validateNamedParameters((Map) null); + operation.validateNamedParameters((Map<String, String>) null); fail("Shouldn't validate without enough parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { @@ -122,7 +119,7 @@ public class RdbmsOperationTests extends TestCase { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); try { - operation.validateParameters(new Object[] {new Integer(1), new Integer(2)}); + operation.validateParameters(new Object[] {1, 2}); fail("Shouldn't validate with too many parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { @@ -134,7 +131,7 @@ public class RdbmsOperationTests extends TestCase { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); try { - Map params = new HashMap(); + Map<String, String> params = new HashMap<String, String>(); params.put("col1", "value"); operation.validateNamedParameters(params); fail("Shouldn't validate with unspecified parameters"); @@ -193,15 +190,12 @@ public class RdbmsOperationTests extends TestCase { DataSource ds = new DriverManagerDataSource(); operation.setDataSource(ds); operation.setSql("select * from mytable where one = ? and two = ?"); - List l = new ArrayList(); - l.add(new SqlParameter("one", Types.NUMERIC)); - l.add(new SqlParameter("two", Types.VARCHAR)); operation.setParameters(new SqlParameter[] { new SqlParameter("one", Types.NUMERIC), new SqlParameter("two", Types.NUMERIC)}); operation.afterPropertiesSet(); try { - operation.validateParameters(new Object[] {new Integer(1), new String("2")}); + operation.validateParameters(new Object[] {1, "2"}); assertEquals(2, operation.getDeclaredParameters().size()); // OK } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java index 3dc5c36d..aee77476 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,13 +27,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.Customer; @@ -106,7 +106,8 @@ public class SqlQueryTests { SqlQuery<Integer> query = new MappingSqlQueryWithParameters<Integer>() { @Override - protected Integer mapRow(ResultSet rs, int rownum, Object[] params, Map context) throws SQLException { + protected Integer mapRow(ResultSet rs, int rownum, Object[] params, Map<? ,?> context) + throws SQLException { assertTrue("params were null", params == null); assertTrue("context was null", context == null); return rs.getInt(1); @@ -728,7 +729,7 @@ public class SqlQueryTests { } @Override - protected Customer updateRow(ResultSet rs, int rownum, Map context) + protected Customer updateRow(ResultSet rs, int rownum, Map<? ,?> context) throws SQLException { rs.updateString(2, "" + context.get(rs.getInt(COLUMN_NAMES[0]))); return null; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java index 718f085b..7791abe4 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.java @@ -24,7 +24,6 @@ import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.Map; - import javax.sql.DataSource; import org.junit.After; @@ -32,6 +31,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.support.GeneratedKeyHolder; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java index d31f7431..73427778 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.java @@ -26,7 +26,6 @@ import java.sql.Types; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.junit.After; @@ -34,6 +33,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.BadSqlGrammarException; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSQLExceptionTranslatorRegistrarTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSQLExceptionTranslatorRegistrarTests.java index 1b3bbd75..7869a5a7 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSQLExceptionTranslatorRegistrarTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSQLExceptionTranslatorRegistrarTests.java @@ -17,6 +17,7 @@ package org.springframework.jdbc.support; import java.sql.SQLException; + import org.junit.Before; import org.junit.Test; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSqlExceptionTranslator.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSqlExceptionTranslator.java index 1b84b2c1..92ad3235 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSqlExceptionTranslator.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/CustomSqlExceptionTranslator.java @@ -16,11 +16,11 @@ package org.springframework.jdbc.support; +import java.sql.SQLException; + import org.springframework.dao.DataAccessException; import org.springframework.dao.TransientDataAccessResourceException; -import java.sql.SQLException; - /** * Custom SQLException translation for testing. * diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java index b1e021d2..f493a743 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,10 +20,10 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer; @@ -39,20 +39,21 @@ import static org.mockito.BDDMockito.*; public class DataFieldMaxValueIncrementerTests { private DataSource dataSource = mock(DataSource.class); + private Connection connection = mock(Connection.class); + private Statement statement = mock(Statement.class); + private ResultSet resultSet = mock(ResultSet.class); + @Test public void testHsqlMaxValueIncrementer() throws SQLException { given(dataSource.getConnection()).willReturn(connection); given(connection.createStatement()).willReturn(statement); - given(statement.executeUpdate("insert into myseq values(null)")).willReturn(1); given(statement.executeQuery("select max(identity()) from myseq")).willReturn(resultSet); given(resultSet.next()).willReturn(true); given(resultSet.getLong(1)).willReturn(0L, 1L, 2L, 3L, 4L, 5L); - given(statement.executeUpdate("delete from myseq where seq < 2")).willReturn(1); - given(statement.executeUpdate("delete from myseq where seq < 5")).willReturn(1); HsqlMaxValueIncrementer incrementer = new HsqlMaxValueIncrementer(); incrementer.setDataSource(dataSource); @@ -67,6 +68,41 @@ public class DataFieldMaxValueIncrementerTests { assertEquals("002", incrementer.nextStringValue()); assertEquals(3, incrementer.nextIntValue()); assertEquals(4, incrementer.nextLongValue()); + + verify(statement, times(6)).executeUpdate("insert into myseq values(null)"); + verify(statement).executeUpdate("delete from myseq where seq < 2"); + verify(statement).executeUpdate("delete from myseq where seq < 5"); + verify(resultSet, times(6)).close(); + verify(statement, times(2)).close(); + verify(connection, times(2)).close(); + } + + @Test + public void testHsqlMaxValueIncrementerWithDeleteSpecificValues() throws SQLException { + given(dataSource.getConnection()).willReturn(connection); + given(connection.createStatement()).willReturn(statement); + given(statement.executeQuery("select max(identity()) from myseq")).willReturn(resultSet); + given(resultSet.next()).willReturn(true); + given(resultSet.getLong(1)).willReturn(0L, 1L, 2L, 3L, 4L, 5L); + + HsqlMaxValueIncrementer incrementer = new HsqlMaxValueIncrementer(); + incrementer.setDataSource(dataSource); + incrementer.setIncrementerName("myseq"); + incrementer.setColumnName("seq"); + incrementer.setCacheSize(3); + incrementer.setPaddingLength(3); + incrementer.setDeleteSpecificValues(true); + incrementer.afterPropertiesSet(); + + assertEquals(0, incrementer.nextIntValue()); + assertEquals(1, incrementer.nextLongValue()); + assertEquals("002", incrementer.nextStringValue()); + assertEquals(3, incrementer.nextIntValue()); + assertEquals(4, incrementer.nextLongValue()); + + verify(statement, times(6)).executeUpdate("insert into myseq values(null)"); + verify(statement).executeUpdate("delete from myseq where seq in (-1, 0, 1)"); + verify(statement).executeUpdate("delete from myseq where seq in (2, 3, 4)"); verify(resultSet, times(6)).close(); verify(statement, times(2)).close(); verify(connection, times(2)).close(); @@ -76,7 +112,6 @@ public class DataFieldMaxValueIncrementerTests { public void testMySQLMaxValueIncrementer() throws SQLException { given(dataSource.getConnection()).willReturn(connection); given(connection.createStatement()).willReturn(statement); - given(statement.executeUpdate("update myseq set seq = last_insert_id(seq + 2)")).willReturn(1); given(statement.executeQuery("select last_insert_id()")).willReturn(resultSet); given(resultSet.next()).willReturn(true); given(resultSet.getLong(1)).willReturn(2L, 4L); @@ -94,6 +129,7 @@ public class DataFieldMaxValueIncrementerTests { assertEquals("3", incrementer.nextStringValue()); assertEquals(4, incrementer.nextLongValue()); + verify(statement, times(2)).executeUpdate("update myseq set seq = last_insert_id(seq + 2)"); verify(resultSet, times(2)).close(); verify(statement, times(2)).close(); verify(connection, times(2)).close(); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/DefaultLobHandlerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/DefaultLobHandlerTests.java index 1426ade1..43f3dc18 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/DefaultLobHandlerTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/DefaultLobHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -26,6 +26,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import org.junit.Test; + import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; @@ -39,10 +40,14 @@ import static org.mockito.BDDMockito.*; public class DefaultLobHandlerTests { private ResultSet rs = mock(ResultSet.class); + private PreparedStatement ps = mock(PreparedStatement.class); + private LobHandler lobHandler = new DefaultLobHandler(); + private LobCreator lobCreator = lobHandler.getLobCreator(); + @Test public void testGetBlobAsBytes() throws SQLException { lobHandler.getBlobAsBytes(rs, 1); @@ -82,13 +87,19 @@ public class DefaultLobHandlerTests { @Test public void testSetBlobAsBinaryStream() throws SQLException, IOException { - InputStream bis = new ByteArrayInputStream("testContent".getBytes()); lobCreator.setBlobAsBinaryStream(ps, 1, bis, 11); verify(ps).setBinaryStream(1, bis, 11); } @Test + public void testSetBlobAsBinaryStreamWithoutLength() throws SQLException, IOException { + InputStream bis = new ByteArrayInputStream("testContent".getBytes()); + lobCreator.setBlobAsBinaryStream(ps, 1, bis, -1); + verify(ps).setBinaryStream(1, bis); + } + + @Test public void testSetClobAsString() throws SQLException, IOException { String content = "testContent"; lobCreator.setClobAsString(ps, 1, content); @@ -103,10 +114,24 @@ public class DefaultLobHandlerTests { } @Test + public void testSetClobAsAsciiStreamWithoutLength() throws SQLException, IOException { + InputStream bis = new ByteArrayInputStream("testContent".getBytes()); + lobCreator.setClobAsAsciiStream(ps, 1, bis, -1); + verify(ps).setAsciiStream(1, bis); + } + + @Test public void testSetClobAsCharacterStream() throws SQLException, IOException { Reader str = new StringReader("testContent"); lobCreator.setClobAsCharacterStream(ps, 1, str, 11); verify(ps).setCharacterStream(1, str, 11); } + @Test + public void testSetClobAsCharacterStreamWithoutLength() throws SQLException, IOException { + Reader str = new StringReader("testContent"); + lobCreator.setClobAsCharacterStream(ps, 1, str, -1); + verify(ps).setCharacterStream(1, str); + } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/KeyHolderTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/KeyHolderTests.java index 68a0a0d8..480b8696 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/KeyHolderTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/KeyHolderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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,13 +18,14 @@ package org.springframework.jdbc.support; import java.util.HashMap; import java.util.LinkedList; +import java.util.List; import java.util.Map; +import junit.framework.TestCase; + import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.InvalidDataAccessApiUsageException; -import junit.framework.TestCase; - /** * Tests for the KeyHolder and GeneratedKeyHolder * and it appears that JdbcUtils doesn't work exactly as documented. @@ -41,17 +42,17 @@ public class KeyHolderTests extends TestCase { } public void testSingleKey(){ - LinkedList l = new LinkedList(); - HashMap m = new HashMap(1); - m.put("key", new Integer(1)); + List<Map<String, Object>> l = new LinkedList<Map<String, Object>>(); + Map<String, Object> m = new HashMap<String, Object>(1); + m.put("key", 1); l.add(m); kh.getKeyList().addAll(l); assertEquals("single key should be returned", 1, kh.getKey().intValue()); } public void testSingleKeyNonNumeric(){ - LinkedList l = new LinkedList(); - HashMap m = new HashMap(1); + List<Map<String, Object>> l = new LinkedList<Map<String, Object>>(); + Map<String, Object> m = new HashMap<String, Object>(1); m.put("key", "1"); l.add(m); kh.getKeyList().addAll(l); @@ -64,8 +65,8 @@ public class KeyHolderTests extends TestCase { } public void testNoKeyReturnedInMap(){ - LinkedList l = new LinkedList(); - HashMap m = new HashMap(); + List<Map<String, Object>> l = new LinkedList<Map<String, Object>>(); + Map<String, Object> m = new HashMap<String, Object>(); l.add(m); kh.getKeyList().addAll(l); try { @@ -77,13 +78,13 @@ public class KeyHolderTests extends TestCase { } public void testMultipleKeys(){ - LinkedList l = new LinkedList(); - HashMap m = new HashMap(1); - m.put("key", new Integer(1)); - m.put("seq", new Integer(2)); + List<Map<String, Object>> l = new LinkedList<Map<String, Object>>(); + Map<String, Object> m = new HashMap<String, Object>(2); + m.put("key", 1); + m.put("seq", 2); l.add(m); kh.getKeyList().addAll(l); - Map keyMap = kh.getKeys(); + Map<String, Object> keyMap = kh.getKeys(); assertEquals("two keys should be in the map", 2, keyMap.size()); try { kh.getKey(); @@ -94,10 +95,10 @@ public class KeyHolderTests extends TestCase { } public void testMultipleKeyRows(){ - LinkedList l = new LinkedList(); - HashMap m = new HashMap(1); - m.put("key", new Integer(1)); - m.put("seq", new Integer(2)); + List<Map<String, Object>> l = new LinkedList<Map<String, Object>>(); + Map<String, Object> m = new HashMap<String, Object>(2); + m.put("key", 1); + m.put("seq", 2); l.add(m); l.add(m); kh.getKeyList().addAll(l); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java index d70991e6..fbefd477 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.sql.Statement; import org.junit.Test; + import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor; import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.java index f7a23fa2..2c9b0902 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -83,7 +83,7 @@ public class SQLErrorCodeSQLExceptionTranslatorTests extends TestCase { assertEquals(sex, bsgex2.getSQLException()); } - private void checkTranslation(SQLExceptionTranslator sext, int errorCode, Class exClass) { + private void checkTranslation(SQLExceptionTranslator sext, int errorCode, Class<?> exClass) { SQLException sex = new SQLException("", "", errorCode); DataAccessException ex = sext.translate("", "", sex); assertTrue(exClass.isInstance(ex)); diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodesFactoryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodesFactoryTests.java index 944b77c5..4e322844 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodesFactoryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodesFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,10 +20,10 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Arrays; - import javax.sql.DataSource; import org.junit.Test; + import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @@ -36,6 +36,7 @@ import static org.mockito.BDDMockito.*; * * @author Rod Johnson * @author Thomas Risberg + * @author Stephane Nicoll */ public class SQLErrorCodesFactoryTests { @@ -120,6 +121,22 @@ public class SQLErrorCodesFactoryTests { assertTrue(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "-204") >= 0); } + private void assertIsHana(SQLErrorCodes sec) { + assertTrue(sec.getBadSqlGrammarCodes().length > 0); + assertTrue(sec.getDataIntegrityViolationCodes().length > 0); + + assertTrue(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "368") >= 0); + assertTrue(Arrays.binarySearch(sec.getPermissionDeniedCodes(), "10") >= 0); + assertTrue(Arrays.binarySearch(sec.getDuplicateKeyCodes(), "301") >= 0); + assertTrue(Arrays.binarySearch(sec.getDataIntegrityViolationCodes(), "461") >= 0); + assertTrue(Arrays.binarySearch(sec.getDataAccessResourceFailureCodes(), "-813") >=0); + assertTrue(Arrays.binarySearch(sec.getInvalidResultSetAccessCodes(), "582") >=0); + assertTrue(Arrays.binarySearch(sec.getCannotAcquireLockCodes(), "131") >= 0); + assertTrue(Arrays.binarySearch(sec.getCannotSerializeTransactionCodes(), "138") >= 0); + assertTrue(Arrays.binarySearch(sec.getDeadlockLoserCodes(), "133") >= 0); + + } + @Test public void testLookupOrder() { class TestSQLErrorCodesFactory extends SQLErrorCodesFactory { @@ -297,6 +314,12 @@ public class SQLErrorCodesFactoryTests { assertIsEmpty(sec); } + @Test + public void testHanaIsRecognizedFromMetadata() throws Exception { + SQLErrorCodes sec = getErrorCodesFromDataSource("SAP DB", null); + assertIsHana(sec); + } + /** * Check that wild card database name works. */ diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionCustomTranslatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionCustomTranslatorTests.java index 9bd769ef..dc90f75b 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionCustomTranslatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionCustomTranslatorTests.java @@ -16,16 +16,16 @@ package org.springframework.jdbc.support; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.TransientDataAccessResourceException; -import org.springframework.jdbc.BadSqlGrammarException; - import java.sql.SQLException; import junit.framework.TestCase; +import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.junit.Test; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.TransientDataAccessResourceException; +import org.springframework.jdbc.BadSqlGrammarException; /** * Class to test custom SQLException translation. diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java index 9f124d15..b0a66036 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java @@ -16,11 +16,10 @@ package org.springframework.jdbc.support; -import static org.junit.Assert.*; - import java.sql.SQLException; import org.junit.Test; + import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; @@ -29,6 +28,8 @@ import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.UncategorizedSQLException; +import static org.junit.Assert.*; + /** * @author Rick Evans * @author Juergen Hoeller diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java index 27e1d96f..1637764d 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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,6 +27,7 @@ import java.sql.Timestamp; import org.junit.Before; import org.junit.Test; + import org.springframework.jdbc.InvalidResultSetAccessException; import static org.junit.Assert.*; @@ -50,21 +51,21 @@ public class ResultSetWrappingRowSetTests { public void testGetBigDecimalInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), BigDecimal.valueOf(1)); + doTest(rset, rowset, 1, BigDecimal.ONE); } @Test public void testGetBigDecimalString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", new Class[] {String.class}); - doTest(rset, rowset, "test", BigDecimal.valueOf(1)); + doTest(rset, rowset, "test", BigDecimal.ONE); } @Test public void testGetStringInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getString", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getString", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), "test"); + doTest(rset, rowset, 1, "test"); } @Test @@ -78,7 +79,7 @@ public class ResultSetWrappingRowSetTests { public void testGetTimestampInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTimestamp", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTimestamp", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Timestamp(1234l)); + doTest(rset, rowset, 1, new Timestamp(1234l)); } @Test @@ -92,7 +93,7 @@ public class ResultSetWrappingRowSetTests { public void testGetDateInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDate", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDate", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Date(1234l)); + doTest(rset, rowset, 1, new Date(1234l)); } @Test @@ -106,7 +107,7 @@ public class ResultSetWrappingRowSetTests { public void testGetTimeInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTime", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTime", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Time(1234l)); + doTest(rset, rowset, 1, new Time(1234l)); } @Test @@ -120,7 +121,7 @@ public class ResultSetWrappingRowSetTests { public void testGetObjectInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getObject", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getObject", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Object()); + doTest(rset, rowset, 1, new Object()); } @Test @@ -134,70 +135,70 @@ public class ResultSetWrappingRowSetTests { public void testGetIntInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Integer(1)); + doTest(rset, rowset, 1, 1); } @Test public void testGetIntString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", new Class[] {String.class}); - doTest(rset, rowset, "test", new Integer(1)); + doTest(rset, rowset, "test", 1); } @Test public void testGetFloatInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Float(1)); + doTest(rset, rowset, 1, 1.0f); } @Test public void testGetFloatString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", new Class[] {String.class}); - doTest(rset, rowset, "test", new Float(1)); + doTest(rset, rowset, "test", 1.0f); } @Test public void testGetDoubleInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Double(1)); + doTest(rset, rowset, 1, 1.0d); } @Test public void testGetDoubleString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", new Class[] {String.class}); - doTest(rset, rowset, "test", new Double(1)); + doTest(rset, rowset, "test", 1.0d); } @Test public void testGetLongInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Long(1)); + doTest(rset, rowset, 1, 1L); } @Test public void testGetLongString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", new Class[] {String.class}); - doTest(rset, rowset, "test", new Long(1)); + doTest(rset, rowset, "test", 1L); } @Test public void testGetBooleanInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); - doTest(rset, rowset, new Integer(1), new Boolean(true)); + doTest(rset, rowset, 1, true); } @Test public void testGetBooleanString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", new Class[] {String.class}); - doTest(rset, rowset, "test", new Boolean(true)); + doTest(rset, rowset, "test", true); } private void doTest(Method rsetMethod, Method rowsetMethod, Object arg, Object ret) throws Exception { |