Merge branch '3.2.x' into master
Conflicts: gradle.properties spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/AbstractLobHandler.java spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java spring-web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -133,7 +133,8 @@ public interface JdbcOperations {
|
||||
* object via a RowMapper.
|
||||
* <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
|
||||
* execute a static query with a PreparedStatement, use the overloaded
|
||||
* {@code queryForObject} method with {@code null} as argument array.
|
||||
* {@link #queryForObject(String, RowMapper, Object...)} method with
|
||||
* {@code null} as argument array.
|
||||
* @param sql SQL query to execute
|
||||
* @param rowMapper object that will map one object per row
|
||||
* @return the single mapped object
|
||||
@@ -148,7 +149,8 @@ public interface JdbcOperations {
|
||||
* Execute a query for a result object, given static SQL.
|
||||
* <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
|
||||
* execute a static query with a PreparedStatement, use the overloaded
|
||||
* {@code queryForObject} method with {@code null} as argument array.
|
||||
* {@link #queryForObject(String, Class, Object...)} method with
|
||||
* {@code null} as argument array.
|
||||
* <p>This method is useful for running static SQL with a known outcome.
|
||||
* The query is expected to be a single row/single column query; the returned
|
||||
* result will be directly mapped to the corresponding object type.
|
||||
@@ -166,7 +168,8 @@ public interface JdbcOperations {
|
||||
* Execute a query for a result Map, given static SQL.
|
||||
* <p>Uses a JDBC Statement, not a PreparedStatement. If you want to
|
||||
* execute a static query with a PreparedStatement, use the overloaded
|
||||
* {@code queryForMap} method with {@code null} as argument array.
|
||||
* {@link #queryForMap(String, Object...)} method with {@code null}
|
||||
* as argument array.
|
||||
* <p>The query is expected to be a single row query; the result row will be
|
||||
* mapped to a Map (one entry for each column, using the column name as the key).
|
||||
* @param sql SQL query to execute
|
||||
@@ -194,7 +197,9 @@ public interface JdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #queryForLong(String, Object[])
|
||||
* @deprecated in favor of {@link #queryForObject(String, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
long queryForLong(String sql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -211,7 +216,9 @@ public interface JdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws DataAccessException if there is any problem executing the query
|
||||
* @see #queryForInt(String, Object[])
|
||||
* @deprecated in favor of {@link #queryForObject(String, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
int queryForInt(String sql) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -712,7 +719,9 @@ public interface JdbcOperations {
|
||||
* @throws DataAccessException if the query fails
|
||||
* @see #queryForLong(String)
|
||||
* @see java.sql.Types
|
||||
* @deprecated in favor of {@link #queryForObject(String, Object[], int[], Class)} )}
|
||||
*/
|
||||
@Deprecated
|
||||
long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -730,7 +739,9 @@ public interface JdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws DataAccessException if the query fails
|
||||
* @see #queryForLong(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, Class, Object[])} )}
|
||||
*/
|
||||
@Deprecated
|
||||
long queryForLong(String sql, Object... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -748,7 +759,9 @@ public interface JdbcOperations {
|
||||
* @throws DataAccessException if the query fails
|
||||
* @see #queryForInt(String)
|
||||
* @see java.sql.Types
|
||||
* @deprecated in favor of {@link #queryForObject(String, Object[], int[], Class)} )}
|
||||
*/
|
||||
@Deprecated
|
||||
int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -766,7 +779,9 @@ public interface JdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws DataAccessException if the query fails
|
||||
* @see #queryForInt(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, Class, Object[])} )}
|
||||
*/
|
||||
@Deprecated
|
||||
int queryForInt(String sql, Object... args) throws DataAccessException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -477,11 +477,13 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||
return queryForObject(sql, getSingleColumnRowMapper(requiredType));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long queryForLong(String sql) throws DataAccessException {
|
||||
Number number = queryForObject(sql, Long.class);
|
||||
return (number != null ? number.longValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int queryForInt(String sql) throws DataAccessException {
|
||||
Number number = queryForObject(sql, Integer.class);
|
||||
return (number != null ? number.intValue() : 0);
|
||||
@@ -757,21 +759,25 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
|
||||
return queryForObject(sql, args, getColumnMapRowMapper());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException {
|
||||
Number number = queryForObject(sql, args, argTypes, Long.class);
|
||||
return (number != null ? number.longValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long queryForLong(String sql, Object... args) throws DataAccessException {
|
||||
Number number = queryForObject(sql, args, Long.class);
|
||||
return (number != null ? number.longValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException {
|
||||
Number number = queryForObject(sql, args, argTypes, Integer.class);
|
||||
return (number != null ? number.intValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int queryForInt(String sql, Object... args) throws DataAccessException {
|
||||
Number number = queryForObject(sql, args, Integer.class);
|
||||
return (number != null ? number.intValue() : 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -146,7 +146,7 @@ public class PreparedStatementCreatorFactory {
|
||||
* Return a new PreparedStatementSetter for the given parameters.
|
||||
* @param params list of parameters (may be {@code null})
|
||||
*/
|
||||
public PreparedStatementSetter newPreparedStatementSetter(List params) {
|
||||
public PreparedStatementSetter newPreparedStatementSetter(List<?> params) {
|
||||
return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList());
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ public class PreparedStatementCreatorFactory {
|
||||
}
|
||||
|
||||
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
PreparedStatement ps;
|
||||
if (generatedKeysColumnNames != null || returnGeneratedKeys) {
|
||||
try {
|
||||
if (generatedKeysColumnNames != null) {
|
||||
@@ -235,10 +235,10 @@ public class PreparedStatementCreatorFactory {
|
||||
ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS);
|
||||
}
|
||||
}
|
||||
catch (AbstractMethodError ex) {
|
||||
catch (AbstractMethodError err) {
|
||||
throw new InvalidDataAccessResourceUsageException(
|
||||
"The JDBC driver is not compliant to JDBC 3.0 and thus " +
|
||||
"does not support retrieval of auto-generated keys", ex);
|
||||
"Your JDBC driver is not compliant with JDBC 3.0 - " +
|
||||
"it does not support retrieval of auto-generated keys", err);
|
||||
}
|
||||
}
|
||||
else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) {
|
||||
@@ -263,7 +263,7 @@ public class PreparedStatementCreatorFactory {
|
||||
int sqlColIndx = 1;
|
||||
for (int i = 0; i < this.parameters.size(); i++) {
|
||||
Object in = this.parameters.get(i);
|
||||
SqlParameter declaredParameter = null;
|
||||
SqlParameter declaredParameter;
|
||||
// SqlParameterValue overrides declared parameter metadata, in particular for
|
||||
// independence from the declared parameter position in case of named parameters.
|
||||
if (in instanceof SqlParameterValue) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,7 @@ import java.math.BigInteger;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ParameterMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
@@ -189,7 +190,7 @@ public abstract class StatementCreatorUtils {
|
||||
if (inValue instanceof SqlParameterValue) {
|
||||
SqlParameterValue parameterValue = (SqlParameterValue) inValue;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Overriding typeinfo with runtime info from SqlParameterValue: column index " + paramIndex +
|
||||
logger.debug("Overriding type info with runtime info from SqlParameterValue: column index " + paramIndex +
|
||||
", SQL type " + parameterValue.getSqlType() +
|
||||
", Type name " + parameterValue.getTypeName());
|
||||
}
|
||||
@@ -228,18 +229,31 @@ public abstract class StatementCreatorUtils {
|
||||
boolean useSetObject = false;
|
||||
sqlType = Types.NULL;
|
||||
try {
|
||||
DatabaseMetaData dbmd = ps.getConnection().getMetaData();
|
||||
String databaseProductName = dbmd.getDatabaseProductName();
|
||||
String jdbcDriverName = dbmd.getDriverName();
|
||||
if (databaseProductName.startsWith("Informix") ||
|
||||
jdbcDriverName.startsWith("Microsoft SQL Server")) {
|
||||
useSetObject = true;
|
||||
ParameterMetaData pmd = null;
|
||||
try {
|
||||
pmd = ps.getParameterMetaData();
|
||||
}
|
||||
else if (databaseProductName.startsWith("DB2") ||
|
||||
jdbcDriverName.startsWith("jConnect") ||
|
||||
jdbcDriverName.startsWith("SQLServer")||
|
||||
jdbcDriverName.startsWith("Apache Derby")) {
|
||||
sqlType = Types.VARCHAR;
|
||||
catch (Throwable ex) {
|
||||
// JDBC driver not compliant with JDBC 3.0
|
||||
// -> proceed with database-specific checks
|
||||
}
|
||||
if (pmd != null) {
|
||||
sqlType = pmd.getParameterType(paramIndex);
|
||||
}
|
||||
else {
|
||||
DatabaseMetaData dbmd = ps.getConnection().getMetaData();
|
||||
String databaseProductName = dbmd.getDatabaseProductName();
|
||||
String jdbcDriverName = dbmd.getDriverName();
|
||||
if (databaseProductName.startsWith("Informix") ||
|
||||
jdbcDriverName.startsWith("Microsoft SQL Server")) {
|
||||
useSetObject = true;
|
||||
}
|
||||
else if (databaseProductName.startsWith("DB2") ||
|
||||
jdbcDriverName.startsWith("jConnect") ||
|
||||
jdbcDriverName.startsWith("SQLServer")||
|
||||
jdbcDriverName.startsWith("Apache Derby")) {
|
||||
sqlType = Types.VARCHAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -56,33 +56,33 @@ public interface CallMetaDataProvider {
|
||||
|
||||
/**
|
||||
* Provide any modification of the procedure name passed in to match the meta data currently used.
|
||||
* This could include alterig the case.
|
||||
* This could include altering the case.
|
||||
*/
|
||||
String procedureNameToUse(String procedureName);
|
||||
|
||||
/**
|
||||
* Provide any modification of the catalog name passed in to match the meta data currently used.
|
||||
* This could include alterig the case.
|
||||
* This could include altering the case.
|
||||
*/
|
||||
String catalogNameToUse(String catalogName);
|
||||
|
||||
/**
|
||||
* Provide any modification of the schema name passed in to match the meta data currently used.
|
||||
* This could include alterig the case.
|
||||
* This could include altering the case.
|
||||
*/
|
||||
String schemaNameToUse(String schemaName);
|
||||
|
||||
/**
|
||||
* Provide any modification of the catalog name passed in to match the meta data currently used.
|
||||
* The reyurned value will be used for meta data lookups. This could include alterig the case used
|
||||
* or providing a base catalog if mone provided.
|
||||
* The returned value will be used for meta data lookups. This could include altering the case used
|
||||
* or providing a base catalog if none is provided.
|
||||
*/
|
||||
String metaDataCatalogNameToUse(String catalogName) ;
|
||||
|
||||
/**
|
||||
* Provide any modification of the schema name passed in to match the meta data currently used.
|
||||
* The reyurned value will be used for meta data lookups. This could include alterig the case used
|
||||
* or providing a base schema if mone provided.
|
||||
* The returned value will be used for meta data lookups. This could include altering the case used
|
||||
* or providing a base schema if none is provided.
|
||||
*/
|
||||
String metaDataSchemaNameToUse(String schemaName) ;
|
||||
|
||||
|
||||
@@ -75,4 +75,4 @@ public class CallParameterMetaData {
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,4 +53,4 @@ public class DerbyTableMetaDataProvider extends GenericTableMetaDataProvider {
|
||||
}
|
||||
return derbysAnswer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -310,7 +310,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||
tmd.setCatalogName(tables.getString("TABLE_CAT"));
|
||||
tmd.setSchemaName(tables.getString("TABLE_SCHEM"));
|
||||
tmd.setTableName(tables.getString("TABLE_NAME"));
|
||||
tmd.setType(tables.getString("TABLE_TYPE"));
|
||||
if (tmd.getSchemaName() == null) {
|
||||
tableMeta.put(userName != null ? userName.toUpperCase() : "", tmd);
|
||||
}
|
||||
@@ -445,7 +444,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||
|
||||
private String tableName;
|
||||
|
||||
private String type;
|
||||
|
||||
public void setCatalogName(String catalogName) {
|
||||
this.catalogName = catalogName;
|
||||
@@ -470,14 +468,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||
public String getTableName() {
|
||||
return this.tableName;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -76,8 +76,8 @@ public interface TableMetaDataProvider {
|
||||
|
||||
/**
|
||||
* Provide any modification of the catalog name passed in to match the meta data currently used.
|
||||
* The reyurned value will be used for meta data lookups. This could include alterig the case used or
|
||||
* providing a base catalog if mone provided.
|
||||
* The returned value will be used for meta data lookups. This could include altering the case used or
|
||||
* providing a base catalog if none is provided.
|
||||
*
|
||||
* @param catalogName
|
||||
* @return catalog name to use
|
||||
@@ -86,8 +86,8 @@ public interface TableMetaDataProvider {
|
||||
|
||||
/**
|
||||
* Provide any modification of the schema name passed in to match the meta data currently used.
|
||||
* The reyurned value will be used for meta data lookups. This could include alterig the case used or
|
||||
* providing a base schema if mone provided.
|
||||
* The returned value will be used for meta data lookups. This could include altering the case used or
|
||||
* providing a base schema if none is provided.
|
||||
*
|
||||
* @param schemaName
|
||||
* @return schema name to use
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.core.namedparam;
|
||||
|
||||
/**
|
||||
* A simple empty implementation of the {@link SqlParameterSource} interface.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2.2
|
||||
*/
|
||||
public class EmptySqlParameterSource implements SqlParameterSource {
|
||||
|
||||
/**
|
||||
* A shared instance of {@link EmptySqlParameterSource}.
|
||||
*/
|
||||
public static final EmptySqlParameterSource INSTANCE = new EmptySqlParameterSource();
|
||||
|
||||
|
||||
public boolean hasValue(String paramName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object getValue(String paramName) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException("This SqlParameterSource is empty");
|
||||
}
|
||||
|
||||
public int getSqlType(String paramName) {
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
public String getTypeName(String paramName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -88,6 +88,21 @@ public interface NamedParameterJdbcOperations {
|
||||
<T> T execute(String sql, Map<String, ?> paramMap, PreparedStatementCallback<T> action)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Execute a JDBC data access operation, implemented as callback action
|
||||
* working on a JDBC PreparedStatement. This allows for implementing arbitrary
|
||||
* data access operations on a single Statement, within Spring's managed
|
||||
* JDBC environment: that is, participating in Spring-managed transactions
|
||||
* and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy.
|
||||
* <p>The callback action can return a result object, for example a
|
||||
* domain object or a collection of domain objects.
|
||||
* @param sql SQL to execute
|
||||
* @param action callback object that specifies the action
|
||||
* @return a result object returned by the action, or {@code null}
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
<T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
* of arguments to bind to the query, reading the ResultSet with a
|
||||
@@ -115,6 +130,19 @@ public interface NamedParameterJdbcOperations {
|
||||
<T> T query(String sql, Map<String, ?> paramMap, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL,
|
||||
* reading the ResultSet with a ResultSetExtractor.
|
||||
* <p>Note: In contrast to the JdbcOperations method with the same signature,
|
||||
* this query variant always uses a PreparedStatement. It is effectively
|
||||
* equivalent to a query call with an empty parameter Map.
|
||||
* @param sql SQL query to execute
|
||||
* @param rse object that will extract results
|
||||
* @return an arbitrary result object, as returned by the ResultSetExtractor
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
*/
|
||||
<T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list of
|
||||
* arguments to bind to the query, reading the ResultSet on a per-row basis
|
||||
@@ -139,6 +167,18 @@ public interface NamedParameterJdbcOperations {
|
||||
*/
|
||||
void query(String sql, Map<String, ?> paramMap, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL,
|
||||
* reading the ResultSet on a per-row basis with a RowCallbackHandler.
|
||||
* <p>Note: In contrast to the JdbcOperations method with the same signature,
|
||||
* this query variant always uses a PreparedStatement. It is effectively
|
||||
* equivalent to a query call with an empty parameter Map.
|
||||
* @param sql SQL query to execute
|
||||
* @param rch object that will extract results, one row at a time
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
*/
|
||||
void query(String sql, RowCallbackHandler rch) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
* of arguments to bind to the query, mapping each row to a Java object
|
||||
@@ -166,6 +206,19 @@ public interface NamedParameterJdbcOperations {
|
||||
<T> List<T> query(String sql, Map<String, ?> paramMap, RowMapper<T> rowMapper)
|
||||
throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL,
|
||||
* mapping each row to a Java object via a RowMapper.
|
||||
* <p>Note: In contrast to the JdbcOperations method with the same signature,
|
||||
* this query variant always uses a PreparedStatement. It is effectively
|
||||
* equivalent to a query call with an empty parameter Map.
|
||||
* @param sql SQL query to execute
|
||||
* @param rowMapper object that will map one object per row
|
||||
* @return the result List, containing mapped objects
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
*/
|
||||
<T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Query given SQL to create a prepared statement from SQL and a list
|
||||
* of arguments to bind to the query, mapping a single result row to a
|
||||
@@ -245,8 +298,7 @@ public interface NamedParameterJdbcOperations {
|
||||
* @param paramSource container of arguments to bind to the query
|
||||
* @return the result Map (one entry for each column, using the column name as the key)
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException
|
||||
* if the query does not return exactly one row, or does not return exactly
|
||||
* one column in that row
|
||||
* if the query does not return exactly one row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
|
||||
* @see org.springframework.jdbc.core.ColumnMapRowMapper
|
||||
@@ -266,8 +318,7 @@ public interface NamedParameterJdbcOperations {
|
||||
* (leaving it to the PreparedStatement to guess the corresponding SQL type)
|
||||
* @return the result Map (one entry for each column, using the column name as the key)
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException
|
||||
* if the query does not return exactly one row, or does not return exactly
|
||||
* one column in that row
|
||||
* if the query does not return exactly one row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String)
|
||||
* @see org.springframework.jdbc.core.ColumnMapRowMapper
|
||||
@@ -287,7 +338,9 @@ public interface NamedParameterJdbcOperations {
|
||||
* one column in that row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, SqlParameterSource, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -304,7 +357,9 @@ public interface NamedParameterJdbcOperations {
|
||||
* one column in that row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, Map, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
long queryForLong(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -319,7 +374,9 @@ public interface NamedParameterJdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, SqlParameterSource, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -335,7 +392,9 @@ public interface NamedParameterJdbcOperations {
|
||||
* exactly one row, or does not return exactly one column in that row
|
||||
* @throws org.springframework.dao.DataAccessException if the query fails
|
||||
* @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String)
|
||||
* @deprecated in favor of {@link #queryForObject(String, Map, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
int queryForInt(String sql, Map<String, ?> paramMap) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -378,8 +437,8 @@ public interface NamedParameterJdbcOperations {
|
||||
* list of arguments to bind to the query, expecting a result list.
|
||||
* <p>The results will be mapped to a List (one entry for each row) of
|
||||
* Maps (one entry for each column, using the column name as the key).
|
||||
* Thus Each element in the list will be of the form returned by this interface's
|
||||
* queryForMap() methods.
|
||||
* Each element in the list will be of the form returned by this interface's
|
||||
* {@code queryForMap} methods.
|
||||
* @param sql SQL query to execute
|
||||
* @param paramSource container of arguments to bind to the query
|
||||
* @return a List that contains a Map per row
|
||||
@@ -394,7 +453,7 @@ public interface NamedParameterJdbcOperations {
|
||||
* <p>The results will be mapped to a List (one entry for each row) of
|
||||
* Maps (one entry for each column, using the column name as the key).
|
||||
* Each element in the list will be of the form returned by this interface's
|
||||
* queryForMap() methods.
|
||||
* {@code queryForMap} methods.
|
||||
* @param sql SQL query to execute
|
||||
* @param paramMap map of parameters to bind to the query
|
||||
* (leaving it to the PreparedStatement to guess the corresponding SQL type)
|
||||
@@ -499,7 +558,7 @@ public interface NamedParameterJdbcOperations {
|
||||
* @param batchValues the array of Maps containing the batch of arguments for the query
|
||||
* @return an array containing the numbers of rows affected by each update in the batch
|
||||
*/
|
||||
public int[] batchUpdate(String sql, Map<String, ?>[] batchValues);
|
||||
int[] batchUpdate(String sql, Map<String, ?>[] batchValues);
|
||||
|
||||
/**
|
||||
* Execute a batch using the supplied SQL statement with the batch of supplied arguments.
|
||||
@@ -507,6 +566,6 @@ public interface NamedParameterJdbcOperations {
|
||||
* @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query
|
||||
* @return an array containing the numbers of rows affected by each update in the batch
|
||||
*/
|
||||
public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs);
|
||||
int[] batchUpdate(String sql, SqlParameterSource[] batchArgs);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -137,6 +137,10 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||
return execute(sql, new MapSqlParameterSource(paramMap), action);
|
||||
}
|
||||
|
||||
public <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
|
||||
return execute(sql, EmptySqlParameterSource.INSTANCE, action);
|
||||
}
|
||||
|
||||
public <T> T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
|
||||
throws DataAccessException {
|
||||
|
||||
@@ -149,6 +153,10 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||
return query(sql, new MapSqlParameterSource(paramMap), rse);
|
||||
}
|
||||
|
||||
public <T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException {
|
||||
return query(sql, EmptySqlParameterSource.INSTANCE, rse);
|
||||
}
|
||||
|
||||
public void query(String sql, SqlParameterSource paramSource, RowCallbackHandler rch)
|
||||
throws DataAccessException {
|
||||
|
||||
@@ -161,6 +169,10 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||
query(sql, new MapSqlParameterSource(paramMap), rch);
|
||||
}
|
||||
|
||||
public void query(String sql, RowCallbackHandler rch) throws DataAccessException {
|
||||
query(sql, EmptySqlParameterSource.INSTANCE, rch);
|
||||
}
|
||||
|
||||
public <T> List<T> query(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
@@ -173,6 +185,10 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||
return query(sql, new MapSqlParameterSource(paramMap), rowMapper);
|
||||
}
|
||||
|
||||
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
|
||||
return query(sql, EmptySqlParameterSource.INSTANCE, rowMapper);
|
||||
}
|
||||
|
||||
public <T> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper)
|
||||
throws DataAccessException {
|
||||
|
||||
@@ -206,20 +222,24 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
|
||||
return queryForObject(sql, paramMap, new ColumnMapRowMapper());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException {
|
||||
Number number = queryForObject(sql, paramSource, Long.class);
|
||||
return (number != null ? number.longValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long queryForLong(String sql, Map<String, ?> paramMap) throws DataAccessException {
|
||||
return queryForLong(sql, new MapSqlParameterSource(paramMap));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException {
|
||||
Number number = queryForObject(sql, paramSource, Integer.class);
|
||||
return (number != null ? number.intValue() : 0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int queryForInt(String sql, Map<String, ?> paramMap) throws DataAccessException {
|
||||
return queryForInt(sql, new MapSqlParameterSource(paramMap));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -97,7 +97,7 @@ public abstract class AbstractJdbcCall {
|
||||
|
||||
|
||||
/**
|
||||
* Get the configured {@link JdbcTemplate}
|
||||
* Get the configured {@link JdbcTemplate}.
|
||||
*/
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
@@ -110,7 +110,6 @@ public abstract class AbstractJdbcCall {
|
||||
return this.callableStatementFactory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the stored procedure.
|
||||
*/
|
||||
@@ -294,7 +293,7 @@ public abstract class AbstractJdbcCall {
|
||||
this.callMetaDataContext.createReturnResultSetParameter(entry.getKey(), entry.getValue());
|
||||
this.declaredParameters.add(resultSetParameter);
|
||||
}
|
||||
callMetaDataContext.processParameters(this.declaredParameters);
|
||||
this.callMetaDataContext.processParameters(this.declaredParameters);
|
||||
|
||||
this.callString = this.callMetaDataContext.createCallString();
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -74,9 +74,9 @@ public abstract class AbstractJdbcInsert {
|
||||
private final List<String> declaredColumns = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Has this operation been compiled? Compilation means at
|
||||
* least checking that a DataSource or JdbcTemplate has been provided,
|
||||
* but subclasses may also implement their own custom validation.
|
||||
* Has this operation been compiled? Compilation means at least checking
|
||||
* that a DataSource or JdbcTemplate has been provided, but subclasses
|
||||
* may also implement their own custom validation.
|
||||
*/
|
||||
private boolean compiled = false;
|
||||
|
||||
@@ -108,9 +108,16 @@ public abstract class AbstractJdbcInsert {
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Methods dealing with configuaration properties
|
||||
// Methods dealing with configuration properties
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the {@link JdbcTemplate} that is configured to be used.
|
||||
*/
|
||||
public JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the table for this insert
|
||||
*/
|
||||
@@ -230,41 +237,31 @@ public abstract class AbstractJdbcInsert {
|
||||
return this.insertTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link JdbcTemplate} that is configured to be used
|
||||
*/
|
||||
protected JdbcTemplate getJdbcTemplate() {
|
||||
return this.jdbcTemplate;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Methods handling compilation issues
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Compile this JdbcInsert using provided parameters and meta data plus other settings. This
|
||||
* finalizes the configuration for this object and subsequent attempts to compile are ignored.
|
||||
* This will be implicitly called the first time an un-compiled insert is executed.
|
||||
* @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't
|
||||
* been correctly initialized, for example if no DataSource has been provided
|
||||
* Compile this JdbcInsert using provided parameters and meta data plus other settings.
|
||||
* This finalizes the configuration for this object and subsequent attempts to compile are
|
||||
* ignored. This will be implicitly called the first time an un-compiled insert is executed.
|
||||
* @throws InvalidDataAccessApiUsageException if the object hasn't been correctly initialized,
|
||||
* for example if no DataSource has been provided
|
||||
*/
|
||||
public synchronized final void compile() throws InvalidDataAccessApiUsageException {
|
||||
if (!isCompiled()) {
|
||||
if (getTableName() == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Table name is required");
|
||||
}
|
||||
|
||||
try {
|
||||
this.jdbcTemplate.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new InvalidDataAccessApiUsageException(ex.getMessage());
|
||||
}
|
||||
|
||||
compileInternal();
|
||||
this.compiled = true;
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("JdbcInsert for table [" + getTableName() + "] compiled");
|
||||
}
|
||||
@@ -272,21 +269,17 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform the actual compilation. Subclasses can override this template method to perform
|
||||
* their own compilation. Invoked after this base class's compilation is complete.
|
||||
* Method to perform the actual compilation. Subclasses can override this template method
|
||||
* to perform their own compilation. Invoked after this base class's compilation is complete.
|
||||
*/
|
||||
protected void compileInternal() {
|
||||
|
||||
tableMetaDataContext.processMetaData(getJdbcTemplate().getDataSource(), getColumnNames(), getGeneratedKeyNames());
|
||||
|
||||
insertString = tableMetaDataContext.createInsertString(getGeneratedKeyNames());
|
||||
|
||||
insertTypes = tableMetaDataContext.createInsertTypes();
|
||||
|
||||
this.tableMetaDataContext.processMetaData(
|
||||
getJdbcTemplate().getDataSource(), getColumnNames(), getGeneratedKeyNames());
|
||||
this.insertString = this.tableMetaDataContext.createInsertString(getGeneratedKeyNames());
|
||||
this.insertTypes = this.tableMetaDataContext.createInsertTypes();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Compiled JdbcInsert. Insert string is [" + getInsertString() + "]");
|
||||
logger.debug("Compiled insert object: insert string is [" + getInsertString() + "]");
|
||||
}
|
||||
|
||||
onCompileInternal();
|
||||
}
|
||||
|
||||
@@ -318,12 +311,13 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check whether we are allowd to make any configuration changes at this time. If the class has been
|
||||
* compiled, then no further changes to the configuration are allowed.
|
||||
* Method to check whether we are allowd to make any configuration changes at this time.
|
||||
* If the class has been compiled, then no further changes to the configuration are allowed.
|
||||
*/
|
||||
protected void checkIfConfigurationModificationIsAllowed() {
|
||||
if (isCompiled()) {
|
||||
throw new InvalidDataAccessApiUsageException("Configuration can't be altered once the class has been compiled or used.");
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"Configuration can't be altered once the class has been compiled or used");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,7 +328,6 @@ public abstract class AbstractJdbcInsert {
|
||||
|
||||
/**
|
||||
* Method that provides execution of the insert using the passed in Map of parameters
|
||||
*
|
||||
* @param args Map with parameter names and values to be used in insert
|
||||
* @return number of rows affected
|
||||
*/
|
||||
@@ -346,7 +339,6 @@ public abstract class AbstractJdbcInsert {
|
||||
|
||||
/**
|
||||
* Method that provides execution of the insert using the passed in {@link SqlParameterSource}
|
||||
*
|
||||
* @param parameterSource parameter names and values to be used in insert
|
||||
* @return number of rows affected
|
||||
*/
|
||||
@@ -357,14 +349,13 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to execute the insert
|
||||
* Method to execute the insert.
|
||||
*/
|
||||
private int executeInsertInternal(List<Object> values) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("The following parameters are used for insert " + getInsertString() + " with: " + values);
|
||||
}
|
||||
int updateCount = jdbcTemplate.update(getInsertString(), values.toArray(), getInsertTypes());
|
||||
return updateCount;
|
||||
return getJdbcTemplate().update(getInsertString(), values.toArray(), getInsertTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,8 +419,8 @@ public abstract class AbstractJdbcInsert {
|
||||
return kh.getKey();
|
||||
}
|
||||
else {
|
||||
throw new DataIntegrityViolationException("Unable to retrieve the generated key for the insert: " +
|
||||
getInsertString());
|
||||
throw new DataIntegrityViolationException(
|
||||
"Unable to retrieve the generated key for the insert: " + getInsertString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +433,7 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
final KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
if (this.tableMetaDataContext.isGetGeneratedKeysSupported()) {
|
||||
jdbcTemplate.update(
|
||||
getJdbcTemplate().update(
|
||||
new PreparedStatementCreator() {
|
||||
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
|
||||
PreparedStatement ps = prepareStatementForGeneratedKeys(con);
|
||||
@@ -467,22 +458,20 @@ public abstract class AbstractJdbcInsert {
|
||||
getGeneratedKeyNames().length + " columns specified: " + Arrays.asList(getGeneratedKeyNames()));
|
||||
}
|
||||
// This is a hack to be able to get the generated key from a database that doesn't support
|
||||
// get generated keys feature. HSQL is one, PostgreSQL is another. Postgres uses a RETURNING
|
||||
// get generated keys feature. HSQL is one, PostgreSQL is another. Postgres uses a RETURNING
|
||||
// clause while HSQL uses a second query that has to be executed with the same connection.
|
||||
final String keyQuery = tableMetaDataContext.getSimulationQueryForGetGeneratedKey(
|
||||
tableMetaDataContext.getTableName(),
|
||||
getGeneratedKeyNames()[0]);
|
||||
final String keyQuery = this.tableMetaDataContext.getSimulationQueryForGetGeneratedKey(
|
||||
this.tableMetaDataContext.getTableName(), getGeneratedKeyNames()[0]);
|
||||
Assert.notNull(keyQuery, "Query for simulating get generated keys can't be null");
|
||||
if (keyQuery.toUpperCase().startsWith("RETURNING")) {
|
||||
Long key = jdbcTemplate.queryForLong(
|
||||
getInsertString() + " " + keyQuery,
|
||||
values.toArray(new Object[values.size()]));
|
||||
HashMap keys = new HashMap(1);
|
||||
Long key = getJdbcTemplate().queryForObject(getInsertString() + " " + keyQuery,
|
||||
values.toArray(new Object[values.size()]), Long.class);
|
||||
Map<String, Object> keys = new HashMap<String, Object>(1);
|
||||
keys.put(getGeneratedKeyNames()[0], key);
|
||||
keyHolder.getKeyList().add(keys);
|
||||
}
|
||||
else {
|
||||
jdbcTemplate.execute(new ConnectionCallback() {
|
||||
getJdbcTemplate().execute(new ConnectionCallback<Object>() {
|
||||
public Object doInConnection(Connection con) throws SQLException, DataAccessException {
|
||||
// Do the insert
|
||||
PreparedStatement ps = null;
|
||||
@@ -490,13 +479,14 @@ public abstract class AbstractJdbcInsert {
|
||||
ps = con.prepareStatement(getInsertString());
|
||||
setParameterValues(ps, values, getInsertTypes());
|
||||
ps.executeUpdate();
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
JdbcUtils.closeStatement(ps);
|
||||
}
|
||||
//Get the key
|
||||
Statement keyStmt = null;
|
||||
ResultSet rs = null;
|
||||
HashMap keys = new HashMap(1);
|
||||
Map<String, Object> keys = new HashMap<String, Object>(1);
|
||||
try {
|
||||
keyStmt = con.createStatement();
|
||||
rs = keyStmt.executeQuery(keyQuery);
|
||||
@@ -505,7 +495,8 @@ public abstract class AbstractJdbcInsert {
|
||||
keys.put(getGeneratedKeyNames()[0], key);
|
||||
keyHolder.getKeyList().add(keys);
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
JdbcUtils.closeResultSet(rs);
|
||||
JdbcUtils.closeStatement(keyStmt);
|
||||
}
|
||||
@@ -547,14 +538,14 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that provides execution of a batch insert using the passed in Maps of parameters
|
||||
*
|
||||
* Method that provides execution of a batch insert using the passed in Maps of parameters.
|
||||
* @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")
|
||||
protected int[] doExecuteBatch(Map<String, Object>[] batch) {
|
||||
checkCompiled();
|
||||
List[] batchValues = new ArrayList[batch.length];
|
||||
List<Object>[] batchValues = new ArrayList[batch.length];
|
||||
int i = 0;
|
||||
for (Map<String, Object> args : batch) {
|
||||
List<Object> values = matchInParameterValuesWithInsertColumns(args);
|
||||
@@ -565,13 +556,13 @@ public abstract class AbstractJdbcInsert {
|
||||
|
||||
/**
|
||||
* Method that provides execution of a batch insert using the passed in array of {@link SqlParameterSource}
|
||||
*
|
||||
* @param batch array of SqlParameterSource with parameter names and values to be used in insert
|
||||
* @return array of number of rows affected
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected int[] doExecuteBatch(SqlParameterSource[] batch) {
|
||||
checkCompiled();
|
||||
List[] batchValues = new ArrayList[batch.length];
|
||||
List<Object>[] batchValues = new ArrayList[batch.length];
|
||||
int i = 0;
|
||||
for (SqlParameterSource parameterSource : batch) {
|
||||
List<Object> values = matchInParameterValuesWithInsertColumns(parameterSource);
|
||||
@@ -581,27 +572,22 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to execute the batch insert
|
||||
* Method to execute the batch insert.
|
||||
*/
|
||||
//TODO synchronize parameter setters with the SimpleJdbcTemplate
|
||||
private int[] executeBatchInternal(final List<Object>[] batchValues) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing statement " + getInsertString() + " with batch of size: " + batchValues.length);
|
||||
}
|
||||
int[] updateCounts = jdbcTemplate.batchUpdate(
|
||||
getInsertString(),
|
||||
return getJdbcTemplate().batchUpdate(getInsertString(),
|
||||
new BatchPreparedStatementSetter() {
|
||||
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
List<Object> values = batchValues[i];
|
||||
setParameterValues(ps, values, getInsertTypes());
|
||||
}
|
||||
|
||||
public int getBatchSize() {
|
||||
return batchValues.length;
|
||||
}
|
||||
});
|
||||
return updateCounts;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -611,6 +597,7 @@ public abstract class AbstractJdbcInsert {
|
||||
*/
|
||||
private void setParameterValues(PreparedStatement preparedStatement, List<Object> values, int[] columnTypes)
|
||||
throws SQLException {
|
||||
|
||||
int colIndex = 0;
|
||||
for (Object value : values) {
|
||||
colIndex++;
|
||||
@@ -624,25 +611,23 @@ public abstract class AbstractJdbcInsert {
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the provided in parameter values with regitered parameters and parameters defined via metedata
|
||||
* processing.
|
||||
*
|
||||
* Match the provided in parameter values with regitered parameters and parameters defined
|
||||
* via metadata processing.
|
||||
* @param parameterSource the parameter vakues provided as a {@link SqlParameterSource}
|
||||
* @return Map with parameter names and values
|
||||
*/
|
||||
protected List<Object> matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) {
|
||||
return tableMetaDataContext.matchInParameterValuesWithInsertColumns(parameterSource);
|
||||
return this.tableMetaDataContext.matchInParameterValuesWithInsertColumns(parameterSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the provided in parameter values with regitered parameters and parameters defined via metedata
|
||||
* processing.
|
||||
*
|
||||
* Match the provided in parameter values with regitered parameters and parameters defined
|
||||
* via metadata processing.
|
||||
* @param args the parameter values provided in a Map
|
||||
* @return Map with parameter names and values
|
||||
*/
|
||||
protected List<Object> matchInParameterValuesWithInsertColumns(Map<String, Object> args) {
|
||||
return tableMetaDataContext.matchInParameterValuesWithInsertColumns(args);
|
||||
return this.tableMetaDataContext.matchInParameterValuesWithInsertColumns(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -128,7 +128,7 @@ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOp
|
||||
/**
|
||||
* @deprecated in favor of {@link #returningResultSet(String, org.springframework.jdbc.core.RowMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated
|
||||
public SimpleJdbcCall returningResultSet(String parameterName, ParameterizedRowMapper rowMapper) {
|
||||
addDeclaredRowMapper(parameterName, rowMapper);
|
||||
return this;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -33,9 +33,9 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||
* name of the table and a Map containing the column names and the column values.
|
||||
*
|
||||
* <p>The meta data processing is based on the DatabaseMetaData provided by the
|
||||
* JDBC driver. As long as the JBDC driver can provide the names of the columns
|
||||
* JDBC driver. As long as the JBDC driver can provide the names of the columns
|
||||
* for a specified table than we can rely on this auto-detection feature. If that
|
||||
* is not the case then the column names must be specified explicitly.
|
||||
* is not the case, then the column names must be specified explicitly.
|
||||
*
|
||||
* <p>The actual insert is being handled using Spring's
|
||||
* {@link org.springframework.jdbc.core.JdbcTemplate}.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,15 +23,16 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.PreparedStatementCallback;
|
||||
import org.springframework.jdbc.support.lob.LobCreator;
|
||||
import org.springframework.jdbc.support.lob.LobHandler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Abstract PreparedStatementCallback implementation that manages a LobCreator.
|
||||
* Abstract {@link PreparedStatementCallback} implementation that manages a {@link LobCreator}.
|
||||
* Typically used as inner class, with access to surrounding method arguments.
|
||||
*
|
||||
* <p>Delegates to the {@code setValues} template method for setting values
|
||||
* on the PreparedStatement, using a given LobCreator for BLOB/CLOB arguments.
|
||||
*
|
||||
* <p>A usage example with JdbcTemplate:
|
||||
* <p>A usage example with {@link org.springframework.jdbc.core.JdbcTemplate}:
|
||||
*
|
||||
* <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // reusable object
|
||||
* LobHandler lobHandler = new DefaultLobHandler(); // reusable object
|
||||
@@ -62,6 +63,7 @@ public abstract class AbstractLobCreatingPreparedStatementCallback implements Pr
|
||||
* @param lobHandler the LobHandler to create LobCreators with
|
||||
*/
|
||||
public AbstractLobCreatingPreparedStatementCallback(LobHandler lobHandler) {
|
||||
Assert.notNull(lobHandler, "LobHandler must not be null");
|
||||
this.lobHandler = lobHandler;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -139,14 +139,18 @@ public abstract class AbstractDriverBasedDataSource extends AbstractDataSource {
|
||||
* @see java.sql.Driver#connect(String, java.util.Properties)
|
||||
*/
|
||||
protected Connection getConnectionFromDriver(String username, String password) throws SQLException {
|
||||
Properties props = new Properties(getConnectionProperties());
|
||||
Properties mergedProps = new Properties();
|
||||
Properties connProps = getConnectionProperties();
|
||||
if (connProps != null) {
|
||||
mergedProps.putAll(connProps);
|
||||
}
|
||||
if (username != null) {
|
||||
props.setProperty("user", username);
|
||||
mergedProps.setProperty("user", username);
|
||||
}
|
||||
if (password != null) {
|
||||
props.setProperty("password", password);
|
||||
mergedProps.setProperty("password", password);
|
||||
}
|
||||
return getConnectionFromDriver(props);
|
||||
return getConnectionFromDriver(mergedProps);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -348,10 +348,6 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
|
||||
return this.newConnectionHolder;
|
||||
}
|
||||
|
||||
public boolean hasTransaction() {
|
||||
return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive());
|
||||
}
|
||||
|
||||
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
|
||||
this.mustRestoreAutoCommit = mustRestoreAutoCommit;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -66,18 +66,17 @@ import org.springframework.core.Constants;
|
||||
* You will get the same effect with non-transactional reads, but lazy fetching
|
||||
* of JDBC Connections allows you to still perform reads in transactions.
|
||||
*
|
||||
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections to
|
||||
* handle lazy fetching of an actual JDBC Connection. Therefore, the returned
|
||||
* Connections cannot be cast to a native JDBC Connection type like OracleConnection,
|
||||
* or to a connection pool implementation type. Use a corresponding
|
||||
* NativeJdbcExtractor to retrieve the native JDBC Connection.
|
||||
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections
|
||||
* (which implement the {@link ConnectionProxy} interface) in order to handle
|
||||
* lazy fetching of an actual JDBC Connection. Therefore, the returned Connections
|
||||
* cannot be cast to a native JDBC Connection type such as OracleConnection or
|
||||
* to a connection pool implementation type. Use a corresponding
|
||||
* {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}
|
||||
* or JDBC 4's {@link Connection#unwrap} to retrieve the native JDBC Connection.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.4
|
||||
* @see ConnectionProxy
|
||||
* @see DataSourceTransactionManager
|
||||
* @see org.springframework.orm.hibernate3.HibernateTransactionManager
|
||||
* @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor
|
||||
*/
|
||||
public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
|
||||
@@ -407,7 +406,13 @@ public class LazyConnectionDataSourceProxy extends DelegatingDataSource {
|
||||
|
||||
// Apply kept transaction settings, if any.
|
||||
if (this.readOnly) {
|
||||
this.target.setReadOnly(this.readOnly);
|
||||
try {
|
||||
this.target.setReadOnly(this.readOnly);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// "read-only not supported" -> ignore, it's just a hint anyway
|
||||
logger.debug("Could not set JDBC Connection read-only", ex);
|
||||
}
|
||||
}
|
||||
if (this.transactionIsolation != null &&
|
||||
!this.transactionIsolation.equals(defaultTransactionIsolation())) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -64,10 +64,10 @@ import org.springframework.util.Assert;
|
||||
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections
|
||||
* (which implement the {@link ConnectionProxy} interface) in order to handle
|
||||
* close calls properly. Therefore, the returned Connections cannot be cast
|
||||
* to a native JDBC Connection type like OracleConnection or to a connection
|
||||
* to a native JDBC Connection type such as OracleConnection or to a connection
|
||||
* pool implementation type. Use a corresponding
|
||||
* {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}
|
||||
* to retrieve the native JDBC Connection.
|
||||
* or JDBC 4's {@link Connection#unwrap} to retrieve the native JDBC Connection.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
|
||||
@@ -205,7 +205,6 @@ public class EmbeddedDatabaseFactory {
|
||||
}
|
||||
|
||||
// getParentLogger() is required for JDBC 4.1 compatibility
|
||||
@SuppressWarnings("unused")
|
||||
public Logger getParentLogger() {
|
||||
return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
}
|
||||
|
||||
@@ -59,4 +59,4 @@ final class HsqlEmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfi
|
||||
properties.setPassword("");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.lang.reflect.Constructor;
|
||||
import java.sql.BatchUpdateException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.core.JdkVersion;
|
||||
@@ -30,9 +29,9 @@ import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DeadlockLoserDataAccessException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.PermissionDeniedDataAccessException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.InvalidResultSetAccessException;
|
||||
|
||||
@@ -201,20 +200,25 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
||||
|
||||
// Check SQLErrorCodes with corresponding error code, if available.
|
||||
if (this.sqlErrorCodes != null) {
|
||||
String errorCode = null;
|
||||
String errorCode;
|
||||
if (this.sqlErrorCodes.isUseSqlStateForTranslation()) {
|
||||
errorCode = sqlEx.getSQLState();
|
||||
}
|
||||
else {
|
||||
errorCode = Integer.toString(sqlEx.getErrorCode());
|
||||
// Try to find SQLException with actual error code, looping through the causes.
|
||||
// E.g. applicable to java.sql.DataTruncation as of JDK 1.6.
|
||||
SQLException current = sqlEx;
|
||||
while (current.getErrorCode() == 0 && current.getCause() instanceof SQLException) {
|
||||
current = (SQLException) current.getCause();
|
||||
}
|
||||
errorCode = Integer.toString(current.getErrorCode());
|
||||
}
|
||||
|
||||
if (errorCode != null) {
|
||||
// Look for defined custom translations first.
|
||||
CustomSQLErrorCodesTranslation[] customTranslations = this.sqlErrorCodes.getCustomTranslations();
|
||||
if (customTranslations != null) {
|
||||
for (int i = 0; i < customTranslations.length; i++) {
|
||||
CustomSQLErrorCodesTranslation customTranslation = customTranslations[i];
|
||||
for (CustomSQLErrorCodesTranslation customTranslation : customTranslations) {
|
||||
if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0) {
|
||||
if (customTranslation.getExceptionClass() != null) {
|
||||
DataAccessException customException = createCustomException(
|
||||
@@ -273,7 +277,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
||||
|
||||
// We couldn't identify it more precisely - let's hand it over to the SQLState fallback translator.
|
||||
if (logger.isDebugEnabled()) {
|
||||
String codes = null;
|
||||
String codes;
|
||||
if (this.sqlErrorCodes != null && this.sqlErrorCodes.isUseSqlStateForTranslation()) {
|
||||
codes = "SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode();
|
||||
}
|
||||
@@ -321,8 +325,8 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
||||
try {
|
||||
int constructorType = 0;
|
||||
Constructor[] constructors = exceptionClass.getConstructors();
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
Class[] parameterTypes = constructors[i].getParameterTypes();
|
||||
for (Constructor constructor : constructors) {
|
||||
Class[] parameterTypes = constructor.getParameterTypes();
|
||||
if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
|
||||
if (constructorType < MESSAGE_ONLY_CONSTRUCTOR)
|
||||
constructorType = MESSAGE_ONLY_CONSTRUCTOR;
|
||||
@@ -350,7 +354,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
||||
}
|
||||
|
||||
// invoke constructor
|
||||
Constructor exceptionConstructor = null;
|
||||
Constructor exceptionConstructor;
|
||||
switch (constructorType) {
|
||||
case MESSAGE_SQL_SQLEX_CONSTRUCTOR:
|
||||
Class[] messageAndSqlAndSqlExArgsClass = new Class[] {String.class, String.class, SQLException.class};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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,7 +22,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Abstract base class for LobHandler implementations.
|
||||
* Abstract base class for {@link LobHandler} implementations.
|
||||
*
|
||||
* <p>Implements all accessor methods for column names through a column lookup
|
||||
* and delegating to the corresponding accessor that takes a column index.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,18 +32,20 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link LobHandler} interface. Invokes
|
||||
* the direct accessor methods that {@code java.sql.ResultSet}
|
||||
* Default implementation of the {@link LobHandler} interface.
|
||||
* Invokes the direct accessor methods that {@code java.sql.ResultSet}
|
||||
* and {@code java.sql.PreparedStatement} offer.
|
||||
*
|
||||
* <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, and only to a limited degree to Oracle 10g!
|
||||
* As a consequence, use {@link OracleLobHandler} for accessing Oracle BLOBs/CLOBs.
|
||||
* This does not apply to Oracle 9i's drivers at all; as of Oracle 10g,
|
||||
* it does work but may still come with LOB size limitations. Consider using
|
||||
* recent Oracle drivers even when working against an older database server.
|
||||
* See the {@link LobHandler} javadoc for the full set of recommendations.
|
||||
*
|
||||
* <p>Some JDBC drivers require values with a BLOB/CLOB target column to be
|
||||
* explicitly set through the JDBC {@code setBlob} / {@code setClob}
|
||||
* API: for example, PostgreSQL's driver. Switch the {@link #setWrapAsLob "wrapAsLob"}
|
||||
* explicitly set through the JDBC {@code setBlob} / {@code setClob} API:
|
||||
* for example, PostgreSQL's driver. Switch the {@link #setWrapAsLob "wrapAsLob"}
|
||||
* property to "true" when operating against such a driver.
|
||||
*
|
||||
* <p>On JDBC 4.0, this LobHandler also supports streaming the BLOB/CLOB content
|
||||
@@ -51,11 +53,15 @@ import org.apache.commons.logging.LogFactory;
|
||||
* argument directly. Consider switching the {@link #setStreamAsLob "streamAsLob"}
|
||||
* property to "true" when operating against a fully compliant JDBC 4.0 driver.
|
||||
*
|
||||
* <p>See the {@link LobHandler} javadoc for a summary of recommendations.
|
||||
* <p>Finally, primarily as a direct equivalent to {@link OracleLobHandler},
|
||||
* this LobHandler also supports the creation of temporary BLOB/CLOB objects.
|
||||
* Consider switching the {@link #setCreateTemporaryLob "createTemporaryLob"}
|
||||
* property to "true" when "streamAsLob" happens to run into LOB size limitations.
|
||||
*
|
||||
* <p>See the {@link LobHandler} interface javadoc for a summary of recommendations.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 04.12.2003
|
||||
* @see #setStreamAsLob
|
||||
* @see java.sql.ResultSet#getBytes
|
||||
* @see java.sql.ResultSet#getBinaryStream
|
||||
* @see java.sql.ResultSet#getString
|
||||
@@ -75,15 +81,18 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
|
||||
private boolean streamAsLob = false;
|
||||
|
||||
private boolean createTemporaryLob = false;
|
||||
|
||||
|
||||
/**
|
||||
* Specify whether to submit a byte array / String to the JDBC driver
|
||||
* wrapped in a JDBC Blob / Clob object, using the JDBC {@code setBlob} /
|
||||
* {@code setClob} method with a Blob / Clob argument.
|
||||
* <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
|
||||
* / {@code setCharacterStream} method for setting the content.
|
||||
* Switch this to "true" for explicit Blob / Clob wrapping against
|
||||
* JDBC drivers that are known to require such wrapping (e.g. PostgreSQL's).
|
||||
* / {@code setCharacterStream} method for setting the content. Switch this
|
||||
* to "true" for explicit Blob / Clob wrapping against JDBC drivers that
|
||||
* are known to require such wrapping (e.g. PostgreSQL's for access to OID
|
||||
* columns, whereas BYTEA columns need to be accessed the standard way).
|
||||
* <p>This setting affects byte array / String arguments as well as stream
|
||||
* arguments, unless {@link #setStreamAsLob "streamAsLob"} overrides this
|
||||
* handling to use JDBC 4.0's new explicit streaming support (if available).
|
||||
@@ -100,7 +109,7 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
* {@code setClob} method with a stream argument.
|
||||
* <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
|
||||
* / {@code setCharacterStream} method for setting the content.
|
||||
* Switch this to "true" for explicit JDBC 4.0 usage, provided that your
|
||||
* Switch this to "true" for explicit JDBC 4.0 streaming, provided that your
|
||||
* JDBC driver actually supports those JDBC 4.0 operations (e.g. Derby's).
|
||||
* <p>This setting affects stream arguments as well as byte array / String
|
||||
* arguments, requiring JDBC 4.0 support. For supporting LOB content against
|
||||
@@ -112,6 +121,23 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
this.streamAsLob = streamAsLob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether to copy a byte array / String into a temporary JDBC
|
||||
* Blob / Clob object created through the JDBC 4.0 {@code createBlob} /
|
||||
* {@code createClob} methods.
|
||||
* <p>Default is "false", using the common JDBC 2.0 {@code setBinaryStream}
|
||||
* / {@code setCharacterStream} method for setting the content. Switch this
|
||||
* to "true" for explicit Blob / Clob creation using JDBC 4.0.
|
||||
* <p>This setting affects stream arguments as well as byte array / String
|
||||
* arguments, requiring JDBC 4.0 support. For supporting LOB content against
|
||||
* JDBC 3.0, check out the {@link #setWrapAsLob "wrapAsLob"} setting.
|
||||
* @see java.sql.Connection#createBlob()
|
||||
* @see java.sql.Connection#createClob()
|
||||
*/
|
||||
public void setCreateTemporaryLob(boolean createTemporaryLob) {
|
||||
this.createTemporaryLob = createTemporaryLob;
|
||||
}
|
||||
|
||||
|
||||
public byte[] getBlobAsBytes(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning BLOB as bytes");
|
||||
@@ -169,12 +195,12 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
}
|
||||
|
||||
public LobCreator getLobCreator() {
|
||||
return new DefaultLobCreator();
|
||||
return (this.createTemporaryLob ? new TemporaryLobCreator() : new DefaultLobCreator());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default LobCreator implementation as inner class.
|
||||
* Default LobCreator implementation as an inner class.
|
||||
* Can be subclassed in DefaultLobHandler extensions.
|
||||
*/
|
||||
protected class DefaultLobCreator implements LobCreator {
|
||||
@@ -268,15 +294,10 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
if (streamAsLob || wrapAsLob) {
|
||||
if (streamAsLob) {
|
||||
if (asciiStream != null) {
|
||||
try {
|
||||
if (streamAsLob) {
|
||||
ps.setClob(paramIndex, new InputStreamReader(asciiStream, "US-ASCII"), contentLength);
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, new PassThroughClob(asciiStream, contentLength));
|
||||
}
|
||||
ps.setClob(paramIndex, new InputStreamReader(asciiStream, "US-ASCII"), contentLength);
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
throw new SQLException("US-ASCII encoding not supported: " + ex);
|
||||
@@ -286,6 +307,14 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
}
|
||||
}
|
||||
else if (wrapAsLob) {
|
||||
if (asciiStream != null) {
|
||||
ps.setClob(paramIndex, new PassThroughClob(asciiStream, contentLength));
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setAsciiStream(paramIndex, asciiStream, contentLength);
|
||||
}
|
||||
@@ -325,7 +354,7 @@ public class DefaultLobHandler extends AbstractLobHandler {
|
||||
}
|
||||
|
||||
public void close() {
|
||||
// nothing to do here
|
||||
// nothing to do when not creating temporary LOBs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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,7 +24,7 @@ import java.sql.SQLException;
|
||||
/**
|
||||
* Abstraction for handling large binary fields and large text fields in
|
||||
* specific databases, no matter if represented as simple types or Large OBjects.
|
||||
* Its main purpose is to isolate Oracle's peculiar handling of LOBs in
|
||||
* Its main purpose is to isolate Oracle 9i's peculiar handling of LOBs in
|
||||
* {@link OracleLobHandler}; most other databases should be able to work
|
||||
* with the provided {@link DefaultLobHandler}.
|
||||
*
|
||||
@@ -45,8 +45,10 @@ import java.sql.SQLException;
|
||||
* proprietary BLOB/CLOB API, and additionally doesn't accept large streams for
|
||||
* PreparedStatement's corresponding setter methods. Therefore, you need to use
|
||||
* {@link OracleLobHandler} there, which uses Oracle's BLOB/CLOB API for both types
|
||||
* of access. The Oracle 10g JDBC driver should basically work with
|
||||
* {@link DefaultLobHandler} as well, with some limitations in terms of LOB sizes.
|
||||
* of access. The Oracle 10g+ JDBC driver will work with {@link DefaultLobHandler}
|
||||
* as well, with some limitations in terms of LOB sizes depending on DBMS setup;
|
||||
* as of Oracle 11g (or actually, using the 11g driver even against older databases),
|
||||
* there should be no need to use {@link OracleLobHandler} at all anymore.
|
||||
*
|
||||
* <p>Of course, you need to declare different field types for each database.
|
||||
* In Oracle, any binary content needs to go into a BLOB, and all character content
|
||||
@@ -57,12 +59,20 @@ import java.sql.SQLException;
|
||||
*
|
||||
* <p><b>Summarizing the recommended options (for actual LOB fields):</b>
|
||||
* <ul>
|
||||
* <li><b>JDBC 4.0 driver:</b> {@link DefaultLobHandler} with {@code streamAsLob=true}.
|
||||
* <li><b>PostgreSQL:</b> {@link DefaultLobHandler} with {@code wrapAsLob=true}.
|
||||
* <li><b>Oracle 9i/10g:</b> {@link OracleLobHandler} with a connection-pool-specific
|
||||
* <li><b>JDBC 4.0 driver (including Oracle 11g driver):</b> Use {@link DefaultLobHandler},
|
||||
* potentially with {@code streamAsLob=true} if your database driver requires that
|
||||
* hint when populating a LOB field. Fall back to {@code createTemporaryLob=true}
|
||||
* if you happen to run into LOB size limitations with your (Oracle) database setup.
|
||||
* <li><b>Oracle 10g driver:</b> Use {@link DefaultLobHandler} with standard setup.
|
||||
* On Oracle 10.1, set the "SetBigStringTryClob" connection property; as of Oracle 10.2,
|
||||
* DefaultLobHandler should work with standard setup out of the box. Alternatively,
|
||||
* consider using the proprietary {@link OracleLobHandler} (see below).
|
||||
* <li><b>Oracle 9i driver:</b> Use {@link OracleLobHandler} with a connection-pool-specific
|
||||
* {@link OracleLobHandler#setNativeJdbcExtractor NativeJdbcExtractor}.
|
||||
* <li><b>PostgreSQL:</b> Configure {@link DefaultLobHandler} with {@code wrapAsLob=true},
|
||||
* and use that LobHandler to access OID columns (but not BYTEA) in your database tables.
|
||||
* <li>For all other database drivers (and for non-LOB fields that might potentially
|
||||
* turn into LOBs on some databases): a plain {@link DefaultLobHandler}.
|
||||
* turn into LOBs on some databases): Simply use a plain {@link DefaultLobHandler}.
|
||||
* </ul>
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -49,14 +49,23 @@ import org.springframework.util.FileCopyUtils;
|
||||
* Note that this LobHandler requires Oracle JDBC driver 9i or higher!
|
||||
*
|
||||
* <p>While most databases are able to work with {@link DefaultLobHandler},
|
||||
* Oracle just accepts Blob/Clob instances created via its own proprietary
|
||||
* BLOB/CLOB API, and additionally doesn't accept large streams for
|
||||
* PreparedStatement's corresponding setter methods. Therefore, you need
|
||||
* to use a strategy like this LobHandler implementation.
|
||||
* Oracle 9i (or more specifically, the Oracle 9i JDBC driver) just accepts
|
||||
* Blob/Clob instances created via its own proprietary BLOB/CLOB API,
|
||||
* and additionally doesn't accept large streams for PreparedStatement's
|
||||
* corresponding setter methods. Therefore, you need to use a strategy like
|
||||
* this LobHandler implementation, or upgrade to the Oracle 10g/11g driver
|
||||
* (which still supports access to Oracle 9i databases).
|
||||
*
|
||||
* <p><b>NOTE: As of Oracle 10.2, {@link DefaultLobHandler} should work equally
|
||||
* well out of the box. On Oracle 11g, JDBC 4.0 based options such as
|
||||
* {@link DefaultLobHandler#setStreamAsLob} and {@link DefaultLobHandler#setCreateTemporaryLob}
|
||||
* are available as well, rendering this proprietary OracleLobHandler obsolete.</b>
|
||||
* Also, consider upgrading to a new driver even when accessing an older database.
|
||||
* See the {@link LobHandler} interface javadoc for a summary of recommendations.
|
||||
*
|
||||
* <p>Needs to work on a native JDBC Connection, to be able to cast it to
|
||||
* {@code oracle.jdbc.OracleConnection}. If you pass in Connections from a
|
||||
* connection pool (the usual case in a J2EE environment), you need to set an
|
||||
* connection pool (the usual case in a Java EE environment), you need to set an
|
||||
* appropriate {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}
|
||||
* to allow for automatic retrieval of the underlying native JDBC Connection.
|
||||
* LobHandler and NativeJdbcExtractor are separate concerns, therefore they
|
||||
@@ -72,8 +81,15 @@ import org.springframework.util.FileCopyUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @author Thomas Risberg
|
||||
* @since 04.12.2003
|
||||
* @see DefaultLobHandler
|
||||
* @see #setNativeJdbcExtractor
|
||||
* @deprecated in favor of {@link DefaultLobHandler} for the Oracle 10g driver and
|
||||
* higher. Consider using the 10g/11g driver even against an Oracle 9i database!
|
||||
* {@link DefaultLobHandler#setCreateTemporaryLob} is the direct equivalent of this
|
||||
* OracleLobHandler's implementation strategy, just using standard JDBC 4.0 API.
|
||||
* That said, in most cases, regular DefaultLobHandler setup will work fine as well.
|
||||
*/
|
||||
@Deprecated
|
||||
public class OracleLobHandler extends AbstractLobHandler {
|
||||
|
||||
private static final String BLOB_CLASS_NAME = "oracle.sql.BLOB";
|
||||
@@ -143,7 +159,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to agressively release any resources used by the LOB. If set to {@code true}
|
||||
* Set whether to aggressively release any resources used by the LOB. If set to {@code true}
|
||||
* then you can only read the LOB values once. Any subsequent reads will fail since the resources
|
||||
* have been closed.
|
||||
* <p>Setting this property to {@code true} can be useful when your queries generates large
|
||||
@@ -283,7 +299,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
||||
((BLOB) lob).open(BLOB.MODE_READONLY);
|
||||
*/
|
||||
Method open = lob.getClass().getMethod("open", int.class);
|
||||
open.invoke(lob, modeReadOnlyConstants.get(lob.getClass()));
|
||||
open.invoke(lob, this.modeReadOnlyConstants.get(lob.getClass()));
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
@@ -366,7 +382,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
||||
*/
|
||||
protected class OracleLobCreator implements LobCreator {
|
||||
|
||||
private final List createdLobs = new LinkedList();
|
||||
private final List<Object> temporaryLobs = new LinkedList<Object>();
|
||||
|
||||
public void setBlobAsBytes(PreparedStatement ps, int paramIndex, final byte[] content)
|
||||
throws SQLException {
|
||||
@@ -495,7 +511,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
||||
Object lob = prepareLob(con, clob ? clobClass : blobClass);
|
||||
callback.populateLob(lob);
|
||||
lob.getClass().getMethod("close", (Class[]) null).invoke(lob, (Object[]) null);
|
||||
this.createdLobs.add(lob);
|
||||
this.temporaryLobs.add(lob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Created new Oracle " + (clob ? "CLOB" : "BLOB"));
|
||||
}
|
||||
@@ -556,7 +572,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
for (Iterator it = this.createdLobs.iterator(); it.hasNext();) {
|
||||
for (Iterator it = this.temporaryLobs.iterator(); it.hasNext();) {
|
||||
/*
|
||||
BLOB blob = (BLOB) it.next();
|
||||
blob.freeTemporary();
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.lob;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* {@link LobCreator} implementation based on temporary LOBs,
|
||||
* using JDBC 4.0's {@link java.sql.Connection#createBlob()} /
|
||||
* {@link java.sql.Connection#createClob()} mechanism.
|
||||
*
|
||||
* <p>Used by DefaultLobHandler's {@link DefaultLobHandler#setCreateTemporaryLob} mode.
|
||||
* Can also be used directly to reuse the tracking and freeing of temporary LOBs.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2.2
|
||||
* @see DefaultLobHandler#setCreateTemporaryLob
|
||||
* @see java.sql.Connection#createBlob()
|
||||
* @see java.sql.Connection#createClob()
|
||||
*/
|
||||
public class TemporaryLobCreator implements LobCreator {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(TemporaryLobCreator.class);
|
||||
|
||||
private final Set<Blob> temporaryBlobs = new LinkedHashSet<Blob>(1);
|
||||
|
||||
private final Set<Clob> temporaryClobs = new LinkedHashSet<Clob>(1);
|
||||
|
||||
|
||||
public void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content)
|
||||
throws SQLException {
|
||||
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
blob.setBytes(1, content);
|
||||
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(content != null ? "Copied bytes into temporary BLOB with length " + content.length :
|
||||
"Set BLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlobAsBinaryStream(
|
||||
PreparedStatement ps, int paramIndex, InputStream binaryStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Blob blob = ps.getConnection().createBlob();
|
||||
try {
|
||||
FileCopyUtils.copy(binaryStream, blob.setBinaryStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
|
||||
this.temporaryBlobs.add(blob);
|
||||
ps.setBlob(paramIndex, blob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(binaryStream != null ?
|
||||
"Copied binary stream into temporary BLOB with length " + contentLength :
|
||||
"Set BLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
public void setClobAsString(PreparedStatement ps, int paramIndex, String content)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
clob.setString(1, content);
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(content != null ? "Copied string into temporary CLOB with length " + content.length() :
|
||||
"Set CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
public void setClobAsAsciiStream(
|
||||
PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(asciiStream, clob.setAsciiStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(asciiStream != null ?
|
||||
"Copied ASCII stream into temporary CLOB with length " + contentLength :
|
||||
"Set CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
public void setClobAsCharacterStream(
|
||||
PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
Clob clob = ps.getConnection().createClob();
|
||||
try {
|
||||
FileCopyUtils.copy(characterStream, clob.setCharacterStream(1));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not copy into LOB stream", ex);
|
||||
}
|
||||
|
||||
this.temporaryClobs.add(clob);
|
||||
ps.setClob(paramIndex, clob);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(characterStream != null ?
|
||||
"Copied character stream into temporary CLOB with length " + contentLength :
|
||||
"Set CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
for (Blob blob : this.temporaryBlobs) {
|
||||
blob.free();
|
||||
}
|
||||
for (Clob clob : this.temporaryClobs) {
|
||||
clob.free();
|
||||
}
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
logger.error("Could not free LOB", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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,7 +24,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link NativeJdbcExtractor} interface for WebLogic,
|
||||
* supporting WebLogic Server 8.1 and higher.
|
||||
* supporting WebLogic Server 9.0 and higher.
|
||||
*
|
||||
* <p>Returns the underlying native Connection to application code instead
|
||||
* of WebLogic's wrapper implementation; unwraps the Connection for native
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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,7 +24,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link NativeJdbcExtractor} interface for WebSphere,
|
||||
* supporting WebSphere Application Server 5.1 and higher.
|
||||
* supporting WebSphere Application Server 6.1 and higher.
|
||||
*
|
||||
* <p>Returns the underlying native Connection to application code instead
|
||||
* of WebSphere's wrapper implementation; unwraps the Connection for
|
||||
@@ -40,14 +40,14 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter {
|
||||
|
||||
private static final String JDBC_ADAPTER_CONNECTION_NAME_5 = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection";
|
||||
private static final String JDBC_ADAPTER_CONNECTION_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection";
|
||||
|
||||
private static final String JDBC_ADAPTER_UTIL_NAME_5 = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil";
|
||||
private static final String JDBC_ADAPTER_UTIL_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil";
|
||||
|
||||
|
||||
private Class webSphere5ConnectionClass;
|
||||
private Class webSphereConnectionClass;
|
||||
|
||||
private Method webSphere5NativeConnectionMethod;
|
||||
private Method webSphereNativeConnectionMethod;
|
||||
|
||||
|
||||
/**
|
||||
@@ -56,10 +56,10 @@ public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter {
|
||||
*/
|
||||
public WebSphereNativeJdbcExtractor() {
|
||||
try {
|
||||
this.webSphere5ConnectionClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_CONNECTION_NAME_5);
|
||||
Class jdbcAdapterUtilClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_UTIL_NAME_5);
|
||||
this.webSphere5NativeConnectionMethod =
|
||||
jdbcAdapterUtilClass.getMethod("getNativeConnection", new Class[] {this.webSphere5ConnectionClass});
|
||||
this.webSphereConnectionClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_CONNECTION_NAME);
|
||||
Class jdbcAdapterUtilClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_UTIL_NAME);
|
||||
this.webSphereNativeConnectionMethod =
|
||||
jdbcAdapterUtilClass.getMethod("getNativeConnection", new Class[] {this.webSphereConnectionClass});
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
@@ -97,9 +97,8 @@ public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter {
|
||||
*/
|
||||
@Override
|
||||
protected Connection doGetNativeConnection(Connection con) throws SQLException {
|
||||
if (this.webSphere5ConnectionClass.isAssignableFrom(con.getClass())) {
|
||||
return (Connection) ReflectionUtils.invokeJdbcMethod(
|
||||
this.webSphere5NativeConnectionMethod, null, new Object[] {con});
|
||||
if (this.webSphereConnectionClass.isAssignableFrom(con.getClass())) {
|
||||
return (Connection) ReflectionUtils.invokeJdbcMethod(this.webSphereNativeConnectionMethod, null, con);
|
||||
}
|
||||
return con;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user