From 07dd61eabdfe73a816cc71b44191afc8bbafcb51 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 15 Feb 2017 18:04:08 +0100 Subject: [PATCH] Drop NativeJdbcExtractor mechanism in favor of JDBC 4 unwrap Issue: SPR-14670 --- .../core/CallableStatementCreatorFactory.java | 27 +-- .../jdbc/core/JdbcTemplate.java | 92 ++------- .../core/PreparedStatementCreatorFactory.java | 29 +-- .../core/metadata/CallMetaDataProvider.java | 4 +- .../GenericTableMetaDataProvider.java | 19 +- .../metadata/OracleTableMetaDataProvider.java | 93 +++++----- .../core/metadata/TableMetaDataContext.java | 16 +- .../core/metadata/TableMetaDataProvider.java | 58 ++---- .../TableMetaDataProviderFactory.java | 24 +-- .../jdbc/core/simple/AbstractJdbcCall.java | 3 +- .../jdbc/core/simple/AbstractJdbcInsert.java | 11 +- .../jdbc/core/simple/SimpleJdbcInsert.java | 9 +- .../simple/SimpleJdbcInsertOperations.java | 13 +- .../support/JdbcBeanDefinitionReader.java | 4 +- .../jdbc/datasource/ConnectionProxy.java | 8 +- .../LazyConnectionDataSourceProxy.java | 9 +- .../SingleConnectionDataSource.java | 9 +- .../TransactionAwareDataSourceProxy.java | 12 +- .../springframework/jdbc/object/SqlCall.java | 3 +- .../jdbc/object/SqlOperation.java | 3 +- .../jdbc/support/JdbcUtils.java | 2 +- .../nativejdbc/C3P0NativeJdbcExtractor.java | 113 ----------- .../nativejdbc/JBossNativeJdbcExtractor.java | 159 ---------------- .../nativejdbc/Jdbc4NativeJdbcExtractor.java | 120 ------------ .../nativejdbc/NativeJdbcExtractor.java | 157 ---------------- .../NativeJdbcExtractorAdapter.java | 175 ------------------ .../OracleJdbc4NativeJdbcExtractor.java | 60 ------ .../nativejdbc/SimpleNativeJdbcExtractor.java | 129 ------------- .../WebLogicNativeJdbcExtractor.java | 105 ----------- .../WebSphereNativeJdbcExtractor.java | 106 ----------- .../jdbc/support/nativejdbc/package-info.java | 7 - .../jdbc/core/JdbcTemplateTests.java | 129 +------------ .../DataSourceTransactionManagerTests.java | 7 - .../support/NativeJdbcExtractorTests.java | 78 -------- .../springframework/orm/jpa/JpaDialect.java | 1 - src/asciidoc/data-access.adoc | 23 --- 36 files changed, 124 insertions(+), 1693 deletions(-) delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/C3P0NativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractorAdapter.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebLogicNativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.java delete mode 100644 spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java delete mode 100644 spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreatorFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreatorFactory.java index 642894871af..ffe32040d3b 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreatorFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreatorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import java.util.List; import java.util.Map; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Helper class that efficiently creates multiple {@link CallableStatementCreator} @@ -49,8 +48,6 @@ public class CallableStatementCreatorFactory { private boolean updatableResults = false; - private NativeJdbcExtractor nativeJdbcExtractor; - /** * Create a new factory. Will need to add parameters via the @@ -100,13 +97,6 @@ public class CallableStatementCreatorFactory { this.updatableResults = updatableResults; } - /** - * Specify the NativeJdbcExtractor to use for unwrapping CallableStatements, if any. - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.nativeJdbcExtractor = nativeJdbcExtractor; - } - /** * Return a new CallableStatementCreator instance given this parameters. @@ -172,12 +162,6 @@ public class CallableStatementCreatorFactory { updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY); } - // Determine CallabeStatement to pass to custom types. - CallableStatement csToUse = cs; - if (nativeJdbcExtractor != null) { - csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs); - } - int sqlColIndx = 1; for (SqlParameter declaredParam : declaredParameters) { if (!declaredParam.isResultsParameter()) { @@ -200,7 +184,7 @@ public class CallableStatementCreatorFactory { } } if (declaredParam.isInputValueProvided()) { - StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue); + StatementCreatorUtils.setParameterValue(cs, sqlColIndx, declaredParam, inValue); } } } @@ -210,7 +194,7 @@ public class CallableStatementCreatorFactory { throw new InvalidDataAccessApiUsageException( "Required input parameter '" + declaredParam.getName() + "' is missing"); } - StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue); + StatementCreatorUtils.setParameterValue(cs, sqlColIndx, declaredParam, inValue); } sqlColIndx++; } @@ -233,10 +217,7 @@ public class CallableStatementCreatorFactory { @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=["); - sb.append(callString).append("]; parameters=").append(this.inParameters); - return sb.toString(); + return "CallableStatementCreator: sql=[" + callString + "]; parameters=" + this.inParameters; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index ee663b101d6..73739eaf35e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -46,7 +46,6 @@ import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcAccessor; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.KeyHolder; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; @@ -104,9 +103,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-"; - /** Custom NativeJdbcExtractor */ - private NativeJdbcExtractor nativeJdbcExtractor; - /** If this variable is false, we will throw exceptions on SQL warnings */ private boolean ignoreWarnings = true; @@ -182,23 +178,6 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } - /** - * Set a NativeJdbcExtractor to extract native JDBC objects from wrapped handles. - * Useful if native Statement and/or ResultSet handles are expected for casting - * to database-specific implementation classes, but a connection pool that wraps - * JDBC objects is used (note: any pool will return wrapped Connections). - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor extractor) { - this.nativeJdbcExtractor = extractor; - } - - /** - * Return the current NativeJdbcExtractor implementation. - */ - public NativeJdbcExtractor getNativeJdbcExtractor() { - return this.nativeJdbcExtractor; - } - /** * Set whether or not we want to ignore SQLWarnings. *

Default is "true", swallowing and logging all warnings. Switch this flag @@ -341,15 +320,8 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { Connection con = DataSourceUtils.getConnection(getDataSource()); try { - Connection conToUse = con; - if (this.nativeJdbcExtractor != null) { - // Extract native JDBC Connection, castable to OracleConnection or the like. - conToUse = this.nativeJdbcExtractor.getNativeConnection(con); - } - else { - // Create close-suppressing Connection proxy, also preparing returned Statements. - conToUse = createConnectionProxy(con); - } + // Create close-suppressing Connection proxy, also preparing returned Statements. + Connection conToUse = createConnectionProxy(con); return action.doInConnection(conToUse); } catch (SQLException ex) { @@ -394,18 +366,9 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { - Connection conToUse = con; - if (this.nativeJdbcExtractor != null && - this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) { - conToUse = this.nativeJdbcExtractor.getNativeConnection(con); - } - stmt = conToUse.createStatement(); + stmt = con.createStatement(); applyStatementSettings(stmt); - Statement stmtToUse = stmt; - if (this.nativeJdbcExtractor != null) { - stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt); - } - T result = action.doInStatement(stmtToUse); + T result = action.doInStatement(stmt); handleWarnings(stmt); return result; } @@ -456,11 +419,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { ResultSet rs = null; try { rs = stmt.executeQuery(sql); - ResultSet rsToUse = rs; - if (nativeJdbcExtractor != null) { - rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); - } - return rse.extractData(rsToUse); + return rse.extractData(rs); } finally { JdbcUtils.closeResultSet(rs); @@ -619,18 +578,9 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { Connection con = DataSourceUtils.getConnection(getDataSource()); PreparedStatement ps = null; try { - Connection conToUse = con; - if (this.nativeJdbcExtractor != null && - this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) { - conToUse = this.nativeJdbcExtractor.getNativeConnection(con); - } - ps = psc.createPreparedStatement(conToUse); + ps = psc.createPreparedStatement(con); applyStatementSettings(ps); - PreparedStatement psToUse = ps; - if (this.nativeJdbcExtractor != null) { - psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps); - } - T result = action.doInPreparedStatement(psToUse); + T result = action.doInPreparedStatement(ps); handleWarnings(ps); return result; } @@ -690,11 +640,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { pss.setValues(ps); } rs = ps.executeQuery(); - ResultSet rsToUse = rs; - if (nativeJdbcExtractor != null) { - rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); - } - return rse.extractData(rsToUse); + return rse.extractData(rs); } finally { JdbcUtils.closeResultSet(rs); @@ -1070,17 +1016,9 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { Connection con = DataSourceUtils.getConnection(getDataSource()); CallableStatement cs = null; try { - Connection conToUse = con; - if (this.nativeJdbcExtractor != null) { - conToUse = this.nativeJdbcExtractor.getNativeConnection(con); - } - cs = csc.createCallableStatement(conToUse); + cs = csc.createCallableStatement(con); applyStatementSettings(cs); - CallableStatement csToUse = cs; - if (this.nativeJdbcExtractor != null) { - csToUse = this.nativeJdbcExtractor.getNativeCallableStatement(cs); - } - T result = action.doInCallableStatement(csToUse); + T result = action.doInCallableStatement(cs); handleWarnings(cs); return result; } @@ -1274,22 +1212,18 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { } Map returnedResults = new HashMap<>(); try { - ResultSet rsToUse = rs; - if (this.nativeJdbcExtractor != null) { - rsToUse = this.nativeJdbcExtractor.getNativeResultSet(rs); - } if (param.getRowMapper() != null) { RowMapper rowMapper = param.getRowMapper(); - Object result = (new RowMapperResultSetExtractor(rowMapper)).extractData(rsToUse); + Object result = (new RowMapperResultSetExtractor(rowMapper)).extractData(rs); returnedResults.put(param.getName(), result); } else if (param.getRowCallbackHandler() != null) { RowCallbackHandler rch = param.getRowCallbackHandler(); - (new RowCallbackHandlerResultSetExtractor(rch)).extractData(rsToUse); + (new RowCallbackHandlerResultSetExtractor(rch)).extractData(rs); returnedResults.put(param.getName(), "ResultSet returned from stored procedure was processed"); } else if (param.getResultSetExtractor() != null) { - Object result = param.getResultSetExtractor().extractData(rsToUse); + Object result = param.getResultSetExtractor().extractData(rs); returnedResults.put(param.getName(), result); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java index cb1a2389c67..22e59af455d 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import java.util.List; import java.util.Set; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.Assert; /** @@ -58,8 +57,6 @@ public class PreparedStatementCreatorFactory { private String[] generatedKeysColumnNames = null; - private NativeJdbcExtractor nativeJdbcExtractor; - /** * Create a new factory. Will need to add parameters via the @@ -133,13 +130,6 @@ public class PreparedStatementCreatorFactory { this.generatedKeysColumnNames = names; } - /** - * Specify the NativeJdbcExtractor to use for unwrapping PreparedStatements, if any. - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.nativeJdbcExtractor = nativeJdbcExtractor; - } - /** * Return a new PreparedStatementSetter for the given parameters. @@ -247,12 +237,6 @@ public class PreparedStatementCreatorFactory { @Override public void setValues(PreparedStatement ps) throws SQLException { - // Determine PreparedStatement to pass to custom types. - PreparedStatement psToUse = ps; - if (nativeJdbcExtractor != null) { - psToUse = nativeJdbcExtractor.getNativePreparedStatement(ps); - } - // Set arguments: Does nothing if there are no parameters. int sqlColIndx = 1; for (int i = 0; i < this.parameters.size(); i++) { @@ -280,16 +264,16 @@ public class PreparedStatementCreatorFactory { if (entry instanceof Object[]) { Object[] valueArray = ((Object[])entry); for (Object argValue : valueArray) { - StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, argValue); + StatementCreatorUtils.setParameterValue(ps, sqlColIndx++, declaredParameter, argValue); } } else { - StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, entry); + StatementCreatorUtils.setParameterValue(ps, sqlColIndx++, declaredParameter, entry); } } } else { - StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, in); + StatementCreatorUtils.setParameterValue(ps, sqlColIndx++, declaredParameter, in); } } } @@ -306,10 +290,7 @@ public class PreparedStatementCreatorFactory { @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=["); - sb.append(sql).append("]; parameters=").append(this.parameters); - return sb.toString(); + return "PreparedStatementCreator: sql=[" + sql + "]; parameters=" + this.parameters; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java index e8ca5fc5415..2991c6d55cd 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.java @@ -45,8 +45,8 @@ public interface CallMetaDataProvider { * This is only called for databases that are supported. This initialization * can be turned off by specifying that column meta data should not be used. * @param databaseMetaData used to retrieve database specific information - * @param catalogName name of catalog to use or null - * @param schemaName name of schema name to use or null + * @param catalogName name of catalog to use (or {@code null} if none) + * @param schemaName name of schema name to use (or {@code null} if none) * @param procedureName name of the stored procedure * @throws SQLException in case of initialization failure * @see org.springframework.jdbc.core.simple.SimpleJdbcCall#withoutProcedureColumnMetaDataAccess() diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java index 6e6586946f7..dca39ff8dca 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java @@ -31,7 +31,6 @@ import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.support.JdbcUtils; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * A generic implementation of the {@link TableMetaDataProvider} that should provide @@ -74,13 +73,10 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** Collection of TableParameterMetaData objects */ private List tableParameterMetaData = new ArrayList<>(); - /** NativeJdbcExtractor that can be used to retrieve the native connection */ - private NativeJdbcExtractor nativeJdbcExtractor; - /** - * Constructor used to initialize with provided database meta data. - * @param databaseMetaData meta data to be used + * Constructor used to initialize with provided database metadata. + * @param databaseMetaData metadata to be used */ protected GenericTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { this.userName = databaseMetaData.getUserName(); @@ -142,15 +138,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { return this.generatedKeysColumnNameArraySupported; } - @Override - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.nativeJdbcExtractor = nativeJdbcExtractor; - } - - protected NativeJdbcExtractor getNativeJdbcExtractor() { - return this.nativeJdbcExtractor; - } - @Override public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { @@ -308,7 +295,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } /** - * Method supporting the metedata processing for a table. + * Method supporting the metadata processing for a table. */ private void locateTableAndProcessMetaData( DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java index 7c827621768..38f6ea59f4d 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +24,12 @@ import java.sql.SQLException; import java.sql.Types; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.ReflectionUtils; /** * Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * Supports a feature for including synonyms in the metadata lookup. Also supports lookup of current schema - * using the sys_context. + * using the {@code sys_context}. * *

Thanks to Mike Youngstrom and Bruce Campbell for submitting the original suggestion for the Oracle * current schema lookup implementation. @@ -46,17 +45,53 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { private String defaultSchema; + /** + * Constructor used to initialize with provided database metadata. + * @param databaseMetaData metadata to be used + */ public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { this(databaseMetaData, false); } - public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData, boolean includeSynonyms) throws SQLException { + /** + * Constructor used to initialize with provided database metadata. + * @param databaseMetaData metadata to be used + * @param includeSynonyms whether to include synonyms + */ + public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData, boolean includeSynonyms) + throws SQLException { + super(databaseMetaData); this.includeSynonyms = includeSynonyms; + lookupDefaultSchema(databaseMetaData); } + /* + * Oracle-based implementation for detecting the current schema. + */ + private void lookupDefaultSchema(DatabaseMetaData databaseMetaData) { + try { + CallableStatement cstmt = null; + try { + cstmt = databaseMetaData.getConnection().prepareCall( + "{? = call sys_context('USERENV', 'CURRENT_SCHEMA')}"); + cstmt.registerOutParameter(1, Types.VARCHAR); + cstmt.execute(); + this.defaultSchema = cstmt.getString(1); + } + finally { + if (cstmt != null) { + cstmt.close(); + } + } + } + catch (SQLException ex) { + logger.debug("Encountered exception during default schema lookup", ex); + } + } + @Override protected String getDefaultSchema() { if (this.defaultSchema != null) { @@ -65,6 +100,7 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { return super.getDefaultSchema(); } + @Override public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException { @@ -76,25 +112,12 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { } Connection con = databaseMetaData.getConnection(); - NativeJdbcExtractor nativeJdbcExtractor = getNativeJdbcExtractor(); - if (nativeJdbcExtractor != null) { - con = nativeJdbcExtractor.getNativeConnection(con); - } - boolean isOracleCon; try { Class oracleConClass = con.getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection"); - isOracleCon = oracleConClass.isInstance(con); - } - catch (ClassNotFoundException ex) { - if (logger.isInfoEnabled()) { - logger.info("Couldn't find Oracle JDBC API: " + ex); - } - isOracleCon = false; + con = (Connection) con.unwrap(oracleConClass); } - - if (!isOracleCon) { - logger.warn("Unable to include synonyms in table metadata lookup. Connection used for " + - "DatabaseMetaData is not recognized as an Oracle connection: " + con); + catch (ClassNotFoundException | SQLException ex) { + logger.warn("Unable to include synonyms in table metadata lookup - no Oracle Connection: " + ex); super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); return; } @@ -112,8 +135,8 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { ReflectionUtils.makeAccessible(setIncludeSynonyms); setIncludeSynonyms.invoke(con, Boolean.TRUE); } - catch (Exception ex) { - throw new InvalidDataAccessApiUsageException("Couldn't prepare Oracle Connection", ex); + catch (Throwable ex) { + throw new InvalidDataAccessApiUsageException("Could not prepare Oracle Connection", ex); } super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); @@ -121,30 +144,8 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { try { setIncludeSynonyms.invoke(con, originalValueForIncludeSynonyms); } - catch (Exception ex) { - throw new InvalidDataAccessApiUsageException("Couldn't reset Oracle Connection", ex); - } - } - - /* - * Oracle-based implementation for detecting the current schema. - */ - private void lookupDefaultSchema(DatabaseMetaData databaseMetaData) { - try { - CallableStatement cstmt = null; - try { - cstmt = databaseMetaData.getConnection().prepareCall("{? = call sys_context('USERENV', 'CURRENT_SCHEMA')}"); - cstmt.registerOutParameter(1, Types.VARCHAR); - cstmt.execute(); - this.defaultSchema = cstmt.getString(1); - } - finally { - if (cstmt != null) { - cstmt.close(); - } - } - } - catch (Exception ignore) { + catch (Throwable ex) { + throw new InvalidDataAccessApiUsageException("Could not reset Oracle Connection", ex); } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java index 9c4c8335deb..e1fbb77f495 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; import org.springframework.jdbc.support.JdbcUtils; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Class to manage context metadata used for the configuration @@ -71,9 +70,6 @@ public class TableMetaDataContext { /** are we using generated key columns */ private boolean generatedKeyColumnsUsed = false; - /** NativeJdbcExtractor to be used to retrieve the native connection */ - NativeJdbcExtractor nativeJdbcExtractor; - /** * Set the name of the table for this context. @@ -187,13 +183,6 @@ public class TableMetaDataContext { return this.metaDataProvider.isGeneratedKeysColumnNameArraySupported(); } - /** - * Set {@link NativeJdbcExtractor} to be used to retrieve the native connection. - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.nativeJdbcExtractor = nativeJdbcExtractor; - } - /** * Process the current meta data with the provided configuration options. @@ -202,8 +191,7 @@ public class TableMetaDataContext { * @param generatedKeyNames name of generated keys */ public void processMetaData(DataSource dataSource, List declaredColumns, String[] generatedKeyNames) { - this.metaDataProvider = - TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor); + this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this); this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java index c7365bed5bc..746fe515d03 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,9 @@ import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; - /** - * Interface specifying the API to be implemented by a class providing table metedata. This is intended for internal use - * by the Simple JDBC classes. + * Interface specifying the API to be implemented by a class providing table metadata. + * This is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 @@ -32,45 +30,37 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; public interface TableMetaDataProvider { /** - * Initialize using the database metedata provided - * @param databaseMetaData - * @throws SQLException + * Initialize using the database metadata provided. + * @param databaseMetaData used to retrieve database specific information + * @throws SQLException in case of initialization failure */ void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException; /** - * Initialize using provided database metadata, table and column information. This initalization can be - * turned off by specifying that column meta data should not be used. + * Initialize using provided database metadata, table and column information. + * This initialization can be turned off by specifying that column meta data should not be used. * @param databaseMetaData used to retrieve database specific information - * @param catalogName name of catalog to use or null - * @param schemaName name of schema name to use or null + * @param catalogName name of catalog to use (or {@code null} if none) + * @param schemaName name of schema name to use (or {@code null} if none) * @param tableName name of the table - * @throws SQLException + * @throws SQLException in case of initialization failure */ - void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) + void initializeWithTableColumnMetaData( + DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException; /** * Get the table name formatted based on metadata information. This could include altering the case. - * - * @param tableName - * @return table name formatted */ String tableNameToUse(String tableName); /** * Get the catalog name formatted based on metadata information. This could include altering the case. - * - * @param catalogName - * @return catalog name formatted */ String catalogNameToUse(String catalogName); /** * Get the schema name formatted based on metadata information. This could include altering the case. - * - * @param schemaName - * @return schema name formatted */ String schemaNameToUse(String schemaName); @@ -78,9 +68,6 @@ public interface TableMetaDataProvider { * Provide any modification of the catalog name passed in to match the meta data currently used. * 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 */ String metaDataCatalogNameToUse(String catalogName) ; @@ -88,9 +75,6 @@ public interface TableMetaDataProvider { * Provide any modification of the schema name passed in to match the meta data currently used. * 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 */ String metaDataSchemaNameToUse(String schemaName) ; @@ -100,15 +84,15 @@ public interface TableMetaDataProvider { boolean isTableColumnMetaDataUsed(); /** - * Does this database support the JDBC 3.0 feature of retreiving generated keys - * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()} + * Does this database support the JDBC 3.0 feature of retrieving generated keys + * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ boolean isGetGeneratedKeysSupported(); /** - * Does this database support a simple quey to retrieve the generated key whe the JDBC 3.0 feature - * of retreiving generated keys is not supported - * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()} + * Does this database support a simple query to retrieve the generated key when + * the JDBC 3.0 feature of retrieving generated keys is not supported? + * @see #isGetGeneratedKeysSupported() */ boolean isGetGeneratedKeysSimulated(); @@ -118,7 +102,7 @@ public interface TableMetaDataProvider { String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName); /** - * Does this database support a column name String array for retreiving generated keys + * Does this database support a column name String array for retrieving generated keys * {@link java.sql.Connection#createStruct(String, Object[])} */ boolean isGeneratedKeysColumnNameArraySupported(); @@ -129,8 +113,4 @@ public interface TableMetaDataProvider { */ List getTableParameterMetaData(); - /** - * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary - */ - void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java index f2e8cc52e10..fe83cef2e9c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.support.DatabaseMetaDataCallback; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.MetaDataAccessException; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Factory used to create a {@link TableMetaDataProvider} implementation @@ -42,24 +41,12 @@ public class TableMetaDataProviderFactory { /** - * Create a TableMetaDataProvider based on the database metedata - * @param dataSource used to retrieve metedata - * @param context the class that holds configuration and metedata + * Create a TableMetaDataProvider based on the database metadata. + * @param dataSource used to retrieve metadata + * @param context the class that holds configuration and metadata * @return instance of the TableMetaDataProvider implementation to be used */ public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, TableMetaDataContext context) { - return createMetaDataProvider(dataSource, context, null); - } - - /** - * Create a TableMetaDataProvider based on the database metedata - * @param dataSource used to retrieve metedata - * @param context the class that holds configuration and metedata - * @param nativeJdbcExtractor the NativeJdbcExtractor to be used - * @return instance of the TableMetaDataProvider implementation to be used - */ - public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, - final TableMetaDataContext context, final NativeJdbcExtractor nativeJdbcExtractor) { try { return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() { @@ -85,9 +72,6 @@ public class TableMetaDataProviderFactory { else { provider = new GenericTableMetaDataProvider(databaseMetaData); } - if (nativeJdbcExtractor != null) { - provider.setNativeJdbcExtractor(nativeJdbcExtractor); - } if (logger.isDebugEnabled()) { logger.debug("Using " + provider.getClass().getSimpleName()); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java index 956b0e62ad5..7fabc20542f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -317,7 +317,6 @@ public abstract class AbstractJdbcCall { this.callableStatementFactory = new CallableStatementCreatorFactory(getCallString(), this.callMetaDataContext.getCallParameters()); - this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java index 6da8212d1fa..f2138c5c773 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,6 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.KeyHolder; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.Assert; /** @@ -104,7 +103,6 @@ public abstract class AbstractJdbcInsert { protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) { Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); this.jdbcTemplate = jdbcTemplate; - setNativeJdbcExtractor(jdbcTemplate.getNativeJdbcExtractor()); } @@ -219,13 +217,6 @@ public abstract class AbstractJdbcInsert { this.tableMetaDataContext.setOverrideIncludeSynonymsDefault(override); } - /** - * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.tableMetaDataContext.setNativeJdbcExtractor(nativeJdbcExtractor); - } - /** * Get the insert string to be used. */ diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java index 417423507fc..d670e448e95 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * A SimpleJdbcInsert is a multi-threaded, reusable object providing easy insert @@ -111,12 +110,6 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn return this; } - @Override - public SimpleJdbcInsertOperations useNativeJdbcExtractorForMetaData(NativeJdbcExtractor nativeJdbcExtractor) { - setNativeJdbcExtractor(nativeJdbcExtractor); - return this; - } - @Override public int execute(Map args) { return doExecute(args); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java index 645a2a9785e..9af301d63ad 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.util.Map; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Interface specifying the API for a Simple JDBC Insert implemented by {@link SimpleJdbcInsert}. @@ -82,16 +81,6 @@ public interface SimpleJdbcInsertOperations { */ SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData(); - /** - * Use a the provided NativeJdbcExtractor during the column meta data - * lookups via JDBC. - * Note: this is only necessary to include when running with a connection pool - * that wraps the meta data connection and when using a database like Oracle - * where it is necessary to access the native connection to include synonyms. - * @return the instance of this SimpleJdbcInsert - */ - SimpleJdbcInsertOperations useNativeJdbcExtractorForMetaData(NativeJdbcExtractor nativeJdbcExtractor); - /** * Execute the insert using the values passed in. diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java index 2af81dd56fe..7008cf81515 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,7 +85,7 @@ public class JdbcBeanDefinitionReader { /** * Set the JdbcTemplate to be used by this bean factory. - * Contains settings for DataSource, SQLExceptionTranslator, NativeJdbcExtractor, etc. + * Contains settings for DataSource, SQLExceptionTranslator, etc. */ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionProxy.java index 1717032fd51..1ed7e5a96e2 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,8 @@ import java.sql.Connection; * Connection proxies. Allows access to the underlying target Connection. * *

This interface can be checked when there is a need to cast to a - * native JDBC Connection such as Oracle's OracleConnection. Spring's - * {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractorAdapter} - * automatically detects such proxies before delegating to the actual - * unwrapping for a specific connection pool. + * native JDBC Connection such as Oracle's OracleConnection. Alternatively, + * all such connections also support JDBC 4.0's {@link Connection#unwrap}. * * @author Juergen Hoeller * @since 1.1 diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java index 743122e7429..8396d1be5bb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,11 +68,8 @@ import org.springframework.core.Constants; * *

NOTE: 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. + * lazy fetching of an actual JDBC Connection. Use {@link Connection#unwrap} + * to retrieve the native JDBC Connection. * * @author Juergen Hoeller * @since 1.1.4 diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java index 9d1411e906a..b7bd8df0df2 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,9 +39,6 @@ import org.springframework.util.ObjectUtils; *

If client code will call {@code close()} in the assumption of a pooled * Connection, like when using persistence tools, set "suppressClose" to "true". * This will return a close-suppressing proxy instead of the physical Connection. - * Be aware that you will not be able to cast this to a native - * {@code OracleConnection} or the like anymore; you need to use a - * {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor} then. * *

This is primarily intended for testing. For example, it enables easy testing * outside an application server, for code that expects to work on a DataSource. @@ -53,10 +50,8 @@ import org.springframework.util.ObjectUtils; * @see #getConnection() * @see java.sql.Connection#close() * @see DataSourceUtils#releaseConnection - * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ -public class SingleConnectionDataSource extends DriverManagerDataSource - implements SmartDataSource, DisposableBean { +public class SingleConnectionDataSource extends DriverManagerDataSource implements SmartDataSource, DisposableBean { /** Create a close-suppressing proxy? */ private boolean suppressClose; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java index 4898699a9da..f90b9bdb42f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,13 +61,9 @@ import org.springframework.util.Assert; * that all operations performed through standard JDBC will automatically participate * in Spring-managed transaction timeouts. * - *

NOTE: 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 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. + *

NOTE: This DataSource proxy needs to return wrapped Connections (which + * implement the {@link ConnectionProxy} interface) in order to handle close calls + * properly. Use {@link Connection#unwrap} to retrieve the native JDBC Connection. * * @author Juergen Hoeller * @since 1.1 diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlCall.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlCall.java index ee70d608d34..6420802d3ff 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlCall.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlCall.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -157,7 +157,6 @@ public abstract class SqlCall extends RdbmsOperation { this.callableStatementFactory = new CallableStatementCreatorFactory(getCallString(), getDeclaredParameters()); this.callableStatementFactory.setResultSetType(getResultSetType()); this.callableStatementFactory.setUpdatableResults(isUpdatableResults()); - this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlOperation.java b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlOperation.java index 2f9cc053ce1..bc85ae180b8 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlOperation.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/object/SqlOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,6 @@ public abstract class SqlOperation extends RdbmsOperation { if (getGeneratedKeysColumnNames() != null) { this.preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames()); } - this.preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java index ef7c972ed82..890013176fd 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java @@ -412,7 +412,7 @@ public abstract class JdbcUtils { /** * Extract a common name for the database in use even if various drivers/platforms provide varying names. - * @param source the name as provided in database metedata + * @param source the name as provided in database metadata * @return the common name to be used */ public static String commonDatabaseName(String source) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/C3P0NativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/C3P0NativeJdbcExtractor.java deleted file mode 100644 index d109506b4ee..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/C3P0NativeJdbcExtractor.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2002-2012 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.nativejdbc; - -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.SQLException; - -import com.mchange.v2.c3p0.C3P0ProxyConnection; - -import org.springframework.util.ReflectionUtils; - -/** - * Implementation of the {@link NativeJdbcExtractor} interface for the - * C3P0 connection pool. - * - *

Returns underlying native Connections to application code instead of C3P0's - * wrapper implementations; unwraps the Connection for native Statements. - * The returned JDBC classes can then safely be cast, e.g. to - * {@code oracle.jdbc.OracleConnection}. - * - *

This NativeJdbcExtractor can be set just to allow working with - * a C3P0 DataSource: If a given object is not a C3P0 wrapper, it will be - * returned as-is. - * - *

Note that this class requires C3P0 0.8.5 or later; for earlier C3P0 versions, - * use SimpleNativeJdbcExtractor (which won't work for C3P0 0.8.5 or later). - * - * @author Juergen Hoeller - * @since 1.1.5 - * @see com.mchange.v2.c3p0.C3P0ProxyConnection#rawConnectionOperation - * @see SimpleNativeJdbcExtractor - */ -public class C3P0NativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - private final Method getRawConnectionMethod; - - - /** - * This method is not meant to be used directly; it rather serves - * as callback method for C3P0's "rawConnectionOperation" API. - * @param con a native Connection handle - * @return the native Connection handle, as-is - */ - public static Connection getRawConnection(Connection con) { - return con; - } - - - public C3P0NativeJdbcExtractor() { - try { - this.getRawConnectionMethod = getClass().getMethod("getRawConnection", new Class[] {Connection.class}); - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("Internal error in C3P0NativeJdbcExtractor: " + ex.getMessage()); - } - } - - - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return true; - } - - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return true; - } - - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return true; - } - - /** - * Retrieve the Connection via C3P0's {@code rawConnectionOperation} API, - * using the {@code getRawConnection} as callback to get access to the - * raw Connection (which is otherwise not directly supported by C3P0). - * @see #getRawConnection - */ - @Override - protected Connection doGetNativeConnection(Connection con) throws SQLException { - if (con instanceof C3P0ProxyConnection) { - C3P0ProxyConnection cpCon = (C3P0ProxyConnection) con; - try { - return (Connection) cpCon.rawConnectionOperation( - this.getRawConnectionMethod, null, new Object[] {C3P0ProxyConnection.RAW_CONNECTION}); - } - catch (SQLException ex) { - throw ex; - } - catch (Exception ex) { - ReflectionUtils.handleReflectionException(ex); - } - } - return con; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.java deleted file mode 100644 index e85a1efedfc..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2002-2012 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.nativejdbc; - -import java.lang.reflect.Method; -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.springframework.util.ReflectionUtils; - -/** - * Implementation of the {@link NativeJdbcExtractor} interface for JBoss, - * supporting JBoss Application Server 3.2.4+. As of Spring 3.1.1, it also - * supports JBoss 7. - * - *

Returns the underlying native Connection, Statement, etc to - * application code instead of JBoss' wrapper implementations. - * The returned JDBC classes can then safely be cast, e.g. to - * {@code oracle.jdbc.OracleConnection}. - * - *

This NativeJdbcExtractor can be set just to allow working with - * a JBoss connection pool: If a given object is not a JBoss wrapper, - * it will be returned as-is. - * - * @author Juergen Hoeller - * @since 03.01.2004 - * @see org.jboss.resource.adapter.jdbc.WrappedConnection#getUnderlyingConnection - * @see org.jboss.resource.adapter.jdbc.WrappedStatement#getUnderlyingStatement - * @see org.jboss.resource.adapter.jdbc.WrappedResultSet#getUnderlyingResultSet - */ -public class JBossNativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - // JBoss 7 - private static final String JBOSS_JCA_PREFIX = "org.jboss.jca.adapters.jdbc."; - - // JBoss <= 6 - private static final String JBOSS_RESOURCE_PREFIX = "org.jboss.resource.adapter.jdbc."; - - - private Class wrappedConnectionClass; - - private Class wrappedStatementClass; - - private Class wrappedResultSetClass; - - private Method getUnderlyingConnectionMethod; - - private Method getUnderlyingStatementMethod; - - private Method getUnderlyingResultSetMethod; - - - /** - * This constructor retrieves JBoss JDBC wrapper classes, - * so we can get the underlying vendor connection using reflection. - */ - public JBossNativeJdbcExtractor() { - String prefix = JBOSS_JCA_PREFIX; - try { - // trying JBoss 7 jca package first... - this.wrappedConnectionClass = getClass().getClassLoader().loadClass(prefix + "WrappedConnection"); - } - catch (ClassNotFoundException ex) { - // JBoss 7 jca package not found -> try traditional resource package. - prefix = JBOSS_RESOURCE_PREFIX; - try { - this.wrappedConnectionClass = getClass().getClassLoader().loadClass(prefix + "WrappedConnection"); - } - catch (ClassNotFoundException ex2) { - throw new IllegalStateException("Could not initialize JBossNativeJdbcExtractor: neither JBoss 7's [" + - JBOSS_JCA_PREFIX + ".WrappedConnection] nor traditional JBoss [" + JBOSS_RESOURCE_PREFIX + - ".WrappedConnection] found"); - } - } - try { - this.wrappedStatementClass = getClass().getClassLoader().loadClass(prefix + "WrappedStatement"); - this.wrappedResultSetClass = getClass().getClassLoader().loadClass(prefix + "WrappedResultSet"); - this.getUnderlyingConnectionMethod = - this.wrappedConnectionClass.getMethod("getUnderlyingConnection", (Class[]) null); - this.getUnderlyingStatementMethod = - this.wrappedStatementClass.getMethod("getUnderlyingStatement", (Class[]) null); - this.getUnderlyingResultSetMethod = - this.wrappedResultSetClass.getMethod("getUnderlyingResultSet", (Class[]) null); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize JBossNativeJdbcExtractor because of missing JBoss API methods/classes: " + ex); - } - } - - - /** - * Retrieve the Connection via JBoss' {@code getUnderlyingConnection} method. - */ - @Override - protected Connection doGetNativeConnection(Connection con) throws SQLException { - if (this.wrappedConnectionClass.isAssignableFrom(con.getClass())) { - return (Connection) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingConnectionMethod, con); - } - return con; - } - - /** - * Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. - */ - @Override - public Statement getNativeStatement(Statement stmt) throws SQLException { - if (this.wrappedStatementClass.isAssignableFrom(stmt.getClass())) { - return (Statement) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingStatementMethod, stmt); - } - return stmt; - } - - /** - * Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. - */ - @Override - public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { - return (PreparedStatement) getNativeStatement(ps); - } - - /** - * Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. - */ - @Override - public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { - return (CallableStatement) getNativeStatement(cs); - } - - /** - * Retrieve the Connection via JBoss' {@code getUnderlyingResultSet} method. - */ - @Override - public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { - if (this.wrappedResultSetClass.isAssignableFrom(rs.getClass())) { - return (ResultSet) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingResultSetMethod, rs); - } - return rs; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java deleted file mode 100644 index b4d34a93640..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2002-2012 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.nativejdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * {@link NativeJdbcExtractor} implementation that delegates to JDBC 4.0's - * {@code unwrap} method, as defined by {@link java.sql.Wrapper}. - * You will typically need to specify a vendor {@link #setConnectionType Connection type} - * / {@link #setStatementType Statement type} / {@link #setResultSetType ResultSet type} - * to extract, since JDBC 4.0 only actually unwraps to a given target type. - * - *

Note: Only use this when actually running against a JDBC 4.0 driver, with a - * connection pool that supports the JDBC 4.0 API (i.e. at least accepts JDBC 4.0 - * API calls and passes them through to the underlying driver)! Other than that, - * there is no need for connection pool specific setup. As of JDBC 4.0, - * NativeJdbcExtractors will typically be implemented for specific drivers - * instead of for specific pools (e.g. {@link OracleJdbc4NativeJdbcExtractor}). - * - * @author Juergen Hoeller - * @since 2.5 - * @see java.sql.Wrapper#unwrap - * @see SimpleNativeJdbcExtractor - * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor - */ -public class Jdbc4NativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - private Class connectionType = Connection.class; - - private Class statementType = Statement.class; - - private Class preparedStatementType = PreparedStatement.class; - - private Class callableStatementType = CallableStatement.class; - - private Class resultSetType = ResultSet.class; - - - /** - * Set the vendor's Connection type, e.g. {@code oracle.jdbc.OracleConnection}. - */ - public void setConnectionType(Class connectionType) { - this.connectionType = connectionType; - } - - /** - * Set the vendor's Statement type, e.g. {@code oracle.jdbc.OracleStatement}. - */ - public void setStatementType(Class statementType) { - this.statementType = statementType; - } - - /** - * Set the vendor's PreparedStatement type, e.g. {@code oracle.jdbc.OraclePreparedStatement}. - */ - public void setPreparedStatementType(Class preparedStatementType) { - this.preparedStatementType = preparedStatementType; - } - - /** - * Set the vendor's CallableStatement type, e.g. {@code oracle.jdbc.OracleCallableStatement}. - */ - public void setCallableStatementType(Class callableStatementType) { - this.callableStatementType = callableStatementType; - } - - /** - * Set the vendor's ResultSet type, e.g. {@code oracle.jdbc.OracleResultSet}. - */ - public void setResultSetType(Class resultSetType) { - this.resultSetType = resultSetType; - } - - - @Override - protected Connection doGetNativeConnection(Connection con) throws SQLException { - return con.unwrap(this.connectionType); - } - - @Override - public Statement getNativeStatement(Statement stmt) throws SQLException { - return stmt.unwrap(this.statementType); - } - - @Override - public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { - return ps.unwrap(this.preparedStatementType); - } - - @Override - public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { - return cs.unwrap(this.callableStatementType); - } - - @Override - public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { - return rs.unwrap(this.resultSetType); - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java deleted file mode 100644 index fef6c7bb9c6..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2002-2016 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.nativejdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -/** - * Interface for extracting native JDBC objects from wrapped objects coming from - * connection pools. This is necessary to allow for casting to native implementations - * like {@code OracleConnection} or {@code OracleResultSet} in application - * code, for example to create Blobs or to access vendor-specific features. - * - *

Note: Setting a custom {@code NativeJdbcExtractor} is just necessary - * if you intend to cast to database-specific implementations like - * {@code OracleConnection} or {@code OracleResultSet}. - * Otherwise, any wrapped JDBC object will be fine, with no need for unwrapping. - * - *

Note: To be able to support any pool's strategy of native ResultSet wrapping, - * it is advisable to get both the native Statement and the native ResultSet - * via this extractor. Some pools just allow to unwrap the Statement, some just to - * unwrap the ResultSet - the above strategy will cover both. It is typically - * not necessary to unwrap the Connection to retrieve a native ResultSet. - * - *

When working with a simple connection pool that wraps Connections but not - * Statements, a {@link SimpleNativeJdbcExtractor} is often sufficient. - * - *

{@link org.springframework.jdbc.core.JdbcTemplate} can properly apply a - * {@code NativeJdbcExtractor} if specified, unwrapping all JDBC objects - * that it creates. Note that this is just necessary if you intend to cast to - * native implementations in your data access code. - * - * @author Juergen Hoeller - * @since 25.08.2003 - * @see SimpleNativeJdbcExtractor - * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor - */ -public interface NativeJdbcExtractor { - - /** - * Return whether it is necessary to work on the native Connection to - * receive native Statements. - *

This should be true if the connection pool does not allow to extract - * the native JDBC objects from its Statement wrapper but supports a way - * to retrieve the native JDBC Connection. This way, applications can - * still receive native Statements and ResultSet via working on the - * native JDBC Connection. - */ - boolean isNativeConnectionNecessaryForNativeStatements(); - - /** - * Return whether it is necessary to work on the native Connection to - * receive native PreparedStatements. - *

This should be true if the connection pool does not allow to extract - * the native JDBC objects from its PreparedStatement wrappers but - * supports a way to retrieve the native JDBC Connection. This way, - * applications can still receive native Statements and ResultSet via - * working on the native JDBC Connection. - */ - boolean isNativeConnectionNecessaryForNativePreparedStatements(); - - /** - * Return whether it is necessary to work on the native Connection to - * receive native CallableStatements. - *

This should be true if the connection pool does not allow to extract - * the native JDBC objects from its CallableStatement wrappers but - * supports a way to retrieve the native JDBC Connection. This way, - * applications can still receive native Statements and ResultSet via - * working on the native JDBC Connection. - */ - boolean isNativeConnectionNecessaryForNativeCallableStatements(); - - /** - * Retrieve the underlying native JDBC Connection for the given Connection. - * Supposed to return the given Connection if not capable of unwrapping. - * @param con the Connection handle, potentially wrapped by a connection pool - * @return the underlying native JDBC Connection, if possible; - * else, the original Connection - * @throws SQLException if thrown by JDBC methods - */ - Connection getNativeConnection(Connection con) throws SQLException; - - /** - * Retrieve the underlying native JDBC Connection for the given Statement. - * Supposed to return the {@code Statement.getConnection()} if not - * capable of unwrapping. - *

Having this extra method allows for more efficient unwrapping if data - * access code already has a Statement. {@code Statement.getConnection()} - * often returns the native JDBC Connection even if the Statement itself - * is wrapped by a pool. - * @param stmt the Statement handle, potentially wrapped by a connection pool - * @return the underlying native JDBC Connection, if possible; - * else, the original Connection - * @throws SQLException if thrown by JDBC methods - * @see java.sql.Statement#getConnection() - */ - Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException; - - /** - * Retrieve the underlying native JDBC Statement for the given Statement. - * Supposed to return the given Statement if not capable of unwrapping. - * @param stmt the Statement handle, potentially wrapped by a connection pool - * @return the underlying native JDBC Statement, if possible; - * else, the original Statement - * @throws SQLException if thrown by JDBC methods - */ - Statement getNativeStatement(Statement stmt) throws SQLException; - - /** - * Retrieve the underlying native JDBC PreparedStatement for the given statement. - * Supposed to return the given PreparedStatement if not capable of unwrapping. - * @param ps the PreparedStatement handle, potentially wrapped by a connection pool - * @return the underlying native JDBC PreparedStatement, if possible; - * else, the original PreparedStatement - * @throws SQLException if thrown by JDBC methods - */ - PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException; - - /** - * Retrieve the underlying native JDBC CallableStatement for the given statement. - * Supposed to return the given CallableStatement if not capable of unwrapping. - * @param cs the CallableStatement handle, potentially wrapped by a connection pool - * @return the underlying native JDBC CallableStatement, if possible; - * else, the original CallableStatement - * @throws SQLException if thrown by JDBC methods - */ - CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException; - - /** - * Retrieve the underlying native JDBC ResultSet for the given statement. - * Supposed to return the given ResultSet if not capable of unwrapping. - * @param rs the ResultSet handle, potentially wrapped by a connection pool - * @return the underlying native JDBC ResultSet, if possible; - * else, the original ResultSet - * @throws SQLException if thrown by JDBC methods - */ - ResultSet getNativeResultSet(ResultSet rs) throws SQLException; - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractorAdapter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractorAdapter.java deleted file mode 100644 index 60d859b7153..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractorAdapter.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2002-2012 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.nativejdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.springframework.jdbc.datasource.DataSourceUtils; - -/** - * Abstract adapter class for the {@link NativeJdbcExtractor} interface, - * for simplified implementation of basic extractors. - * Basically returns the passed-in JDBC objects on all methods. - * - *

{@code getNativeConnection} checks for a ConnectionProxy chain, - * for example from a TransactionAwareDataSourceProxy, before delegating to - * {@code doGetNativeConnection} for actual unwrapping. You can override - * either of the two for a specific connection pool, but the latter is - * recommended to participate in ConnectionProxy unwrapping. - * - *

{@code getNativeConnection} also applies a fallback if the first - * native extraction process failed, that is, returned the same Connection as - * passed in. It assumes that some additional proxying is going in this case: - * Hence, it retrieves the underlying native Connection from the DatabaseMetaData - * via {@code conHandle.getMetaData().getConnection()} and retries the native - * extraction process based on that Connection handle. This works, for example, - * for the Connection proxies exposed by Hibernate 3.1's {@code Session.connection()}. - * - *

The {@code getNativeConnectionFromStatement} method is implemented - * to simply delegate to {@code getNativeConnection} with the Statement's - * Connection. This is what most extractor implementations will stick to, - * unless there's a more efficient version for a specific pool. - * - * @author Juergen Hoeller - * @since 1.1 - * @see #getNativeConnection - * @see #getNativeConnectionFromStatement - * @see org.springframework.jdbc.datasource.ConnectionProxy - */ -public abstract class NativeJdbcExtractorAdapter implements NativeJdbcExtractor { - - /** - * Return {@code false} by default. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return false; - } - - /** - * Return {@code false} by default. - */ - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return false; - } - - /** - * Return {@code false} by default. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return false; - } - - /** - * Check for a ConnectionProxy chain, then delegate to doGetNativeConnection. - *

ConnectionProxy is used by Spring's TransactionAwareDataSourceProxy - * and LazyConnectionDataSourceProxy. The target connection behind it is - * typically one from a local connection pool, to be unwrapped by the - * doGetNativeConnection implementation of a concrete subclass. - * @see #doGetNativeConnection - * @see org.springframework.jdbc.datasource.ConnectionProxy - * @see org.springframework.jdbc.datasource.DataSourceUtils#getTargetConnection - * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy - * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy - */ - @Override - public Connection getNativeConnection(Connection con) throws SQLException { - if (con == null) { - return null; - } - Connection targetCon = DataSourceUtils.getTargetConnection(con); - Connection nativeCon = doGetNativeConnection(targetCon); - if (nativeCon == targetCon) { - // We haven't received a different Connection, so we'll assume that there's - // some additional proxying going on. Let's check whether we get something - // different back from the DatabaseMetaData.getConnection() call. - DatabaseMetaData metaData = targetCon.getMetaData(); - // The following check is only really there for mock Connections - // which might not carry a DatabaseMetaData instance. - if (metaData != null) { - Connection metaCon = metaData.getConnection(); - if (metaCon != null && metaCon != targetCon) { - // We've received a different Connection there: - // Let's retry the native extraction process with it. - nativeCon = doGetNativeConnection(metaCon); - } - } - } - return nativeCon; - } - - /** - * Not able to unwrap: return passed-in Connection. - */ - protected Connection doGetNativeConnection(Connection con) throws SQLException { - return con; - } - - /** - * Retrieve the Connection via the Statement's Connection. - * @see #getNativeConnection - * @see Statement#getConnection - */ - @Override - public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException { - if (stmt == null) { - return null; - } - return getNativeConnection(stmt.getConnection()); - } - - /** - * Not able to unwrap: return passed-in Statement. - */ - @Override - public Statement getNativeStatement(Statement stmt) throws SQLException { - return stmt; - } - - /** - * Not able to unwrap: return passed-in PreparedStatement. - */ - @Override - public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { - return ps; - } - - /** - * Not able to unwrap: return passed-in CallableStatement. - */ - @Override - public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { - return cs; - } - - /** - * Not able to unwrap: return passed-in ResultSet. - */ - @Override - public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { - return rs; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java deleted file mode 100644 index 1446c894360..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2012 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.nativejdbc; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.Statement; - -/** - * A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver, - * specifying the following vendor-specific API types for unwrapping: - *

- * - *

Note: This will work with any JDBC 4.0 compliant connection pool, without a need for - * connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors - * will typically be implemented for specific drivers instead of for specific pools. - * - * @author Juergen Hoeller - * @since 3.0.5 - */ -public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor { - - @SuppressWarnings("unchecked") - public OracleJdbc4NativeJdbcExtractor() { - try { - setConnectionType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection")); - setStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement")); - setPreparedStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement")); - setCallableStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement")); - setResultSetType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet")); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex); - } - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java deleted file mode 100644 index f7c0617ccbd..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2002-2016 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.nativejdbc; - -/** - * A simple implementation of the {@link NativeJdbcExtractor} interface. - * Assumes a pool that wraps Connection handles but not DatabaseMetaData: - * In this case, the underlying native Connection can be retrieved by simply - * calling {@code conHandle.getMetaData().getConnection()}. - * All other JDBC objects will be returned as passed in. - * - *

This extractor should work with any pool that does not wrap DatabaseMetaData, - * and will also work with any plain JDBC driver. Note that a pool can still wrap - * Statements, PreparedStatements, etc: The only requirement of this extractor is - * that {@code java.sql.DatabaseMetaData} does not get wrapped, returning the - * native Connection of the JDBC driver on {@code metaData.getConnection()}. - * - *

Customize this extractor by setting the "nativeConnectionNecessaryForXxx" - * flags accordingly: If Statements, PreparedStatements, and/or CallableStatements - * are wrapped by your pool, set the corresponding "nativeConnectionNecessaryForXxx" - * flags to "true". If none of the statement types is wrapped - or you solely need - * Connection unwrapping in the first place -, the defaults are fine. - * - *

For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping: - *

- * - * @author Juergen Hoeller - * @since 05.12.2003 - * @see #setNativeConnectionNecessaryForNativeStatements - * @see #setNativeConnectionNecessaryForNativePreparedStatements - * @see #setNativeConnectionNecessaryForNativeCallableStatements - * @see Jdbc4NativeJdbcExtractor - * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor - */ -public class SimpleNativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - private boolean nativeConnectionNecessaryForNativeStatements = false; - - private boolean nativeConnectionNecessaryForNativePreparedStatements = false; - - private boolean nativeConnectionNecessaryForNativeCallableStatements = false; - - - /** - * Set whether it is necessary to work on the native Connection to - * receive native Statements. Default is "false". If true, the Connection - * will be unwrapped first to create a Statement. - *

This makes sense if you need to work with native Statements from - * a pool that does not allow to extract the native JDBC objects from its - * wrappers but returns the native Connection on DatabaseMetaData.getConnection. - *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, - * so set this to true if your connection pool wraps Statements. - * @see java.sql.Connection#createStatement - * @see java.sql.DatabaseMetaData#getConnection - */ - public void setNativeConnectionNecessaryForNativeStatements(boolean nativeConnectionNecessaryForNativeStatements) { - this.nativeConnectionNecessaryForNativeStatements = nativeConnectionNecessaryForNativeStatements; - } - - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return this.nativeConnectionNecessaryForNativeStatements; - } - - /** - * Set whether it is necessary to work on the native Connection to - * receive native PreparedStatements. Default is "false". If true, - * the Connection will be unwrapped first to create a PreparedStatement. - *

This makes sense if you need to work with native PreparedStatements from - * a pool that does not allow to extract the native JDBC objects from its - * wrappers but returns the native Connection on Statement.getConnection. - *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, - * so set this to true if your connection pool wraps PreparedStatements. - * @see java.sql.Connection#prepareStatement - * @see java.sql.DatabaseMetaData#getConnection - */ - public void setNativeConnectionNecessaryForNativePreparedStatements(boolean nativeConnectionNecessary) { - this.nativeConnectionNecessaryForNativePreparedStatements = nativeConnectionNecessary; - } - - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return this.nativeConnectionNecessaryForNativePreparedStatements; - } - - /** - * Set whether it is necessary to work on the native Connection to - * receive native CallableStatements. Default is "false". If true, - * the Connection will be unwrapped first to create a CallableStatement. - *

This makes sense if you need to work with native CallableStatements from - * a pool that does not allow to extract the native JDBC objects from its - * wrappers but returns the native Connection on Statement.getConnection. - *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, - * so set this to true if your connection pool wraps CallableStatements. - * @see java.sql.Connection#prepareCall - * @see java.sql.DatabaseMetaData#getConnection - */ - public void setNativeConnectionNecessaryForNativeCallableStatements(boolean nativeConnectionNecessary) { - this.nativeConnectionNecessaryForNativeCallableStatements = nativeConnectionNecessary; - } - - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return this.nativeConnectionNecessaryForNativeCallableStatements; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebLogicNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebLogicNativeJdbcExtractor.java deleted file mode 100644 index aa77ddca68a..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebLogicNativeJdbcExtractor.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.nativejdbc; - -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.SQLException; - -import org.springframework.util.ReflectionUtils; - -/** - * Implementation of the {@link NativeJdbcExtractor} interface for WebLogic, - * supporting WebLogic Server 9.0 and higher. - * - *

Returns the underlying native Connection to application code instead - * of WebLogic's wrapper implementation; unwraps the Connection for native - * statements. The returned JDBC classes can then safely be cast, e.g. to - * {@code oracle.jdbc.OracleConnection}. - * - *

This NativeJdbcExtractor can be set just to allow working - * with a WebLogic DataSource: If a given object is not a WebLogic - * Connection wrapper, it will be returned as-is. - * - * @author Thomas Risberg - * @author Juergen Hoeller - * @since 1.0.2 - * @see #getNativeConnection - * @see weblogic.jdbc.extensions.WLConnection#getVendorConnection - */ -public class WebLogicNativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - private static final String JDBC_EXTENSION_NAME = "weblogic.jdbc.extensions.WLConnection"; - - - private final Class jdbcExtensionClass; - - private final Method getVendorConnectionMethod; - - - /** - * This constructor retrieves the WebLogic JDBC extension interface, - * so we can get the underlying vendor connection using reflection. - */ - public WebLogicNativeJdbcExtractor() { - try { - this.jdbcExtensionClass = getClass().getClassLoader().loadClass(JDBC_EXTENSION_NAME); - this.getVendorConnectionMethod = this.jdbcExtensionClass.getMethod("getVendorConnection", (Class[]) null); - } - catch (Exception ex) { - throw new IllegalStateException( - "Could not initialize WebLogicNativeJdbcExtractor because WebLogic API classes are not available: " + ex); - } - } - - - /** - * Return {@code true}, as WebLogic returns wrapped Statements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return true; - } - - /** - * Return {@code true}, as WebLogic returns wrapped PreparedStatements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return true; - } - - /** - * Return {@code true}, as WebLogic returns wrapped CallableStatements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return true; - } - - /** - * Retrieve the Connection via WebLogic's {@code getVendorConnection} method. - */ - @Override - protected Connection doGetNativeConnection(Connection con) throws SQLException { - if (this.jdbcExtensionClass.isAssignableFrom(con.getClass())) { - return (Connection) ReflectionUtils.invokeJdbcMethod(this.getVendorConnectionMethod, con); - } - return con; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.java deleted file mode 100644 index 55e818d3818..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.nativejdbc; - -import java.lang.reflect.Method; -import java.sql.Connection; -import java.sql.SQLException; - -import org.springframework.util.ReflectionUtils; - -/** - * Implementation of the {@link NativeJdbcExtractor} interface for WebSphere, - * supporting WebSphere Application Server 6.1 and higher. - * - *

Returns the underlying native Connection to application code instead - * of WebSphere's wrapper implementation; unwraps the Connection for - * native statements. The returned JDBC classes can then safely be cast, - * e.g. to {@code oracle.jdbc.OracleConnection}. - * - *

This NativeJdbcExtractor can be set just to allow working - * with a WebSphere DataSource: If a given object is not a WebSphere - * Connection wrapper, it will be returned as-is. - * - * @author Juergen Hoeller - * @since 1.1 - */ -public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - private static final String JDBC_ADAPTER_CONNECTION_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection"; - - private static final String JDBC_ADAPTER_UTIL_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil"; - - - private Class webSphereConnectionClass; - - private Method webSphereNativeConnectionMethod; - - - /** - * This constructor retrieves WebSphere JDBC adapter classes, - * so we can get the underlying vendor connection using reflection. - */ - public WebSphereNativeJdbcExtractor() { - try { - 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( - "Could not initialize WebSphereNativeJdbcExtractor because WebSphere API classes are not available: " + ex); - } - } - - - /** - * Return {@code true}, as WebSphere returns wrapped Statements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return true; - } - - /** - * Return {@code true}, as WebSphere returns wrapped PreparedStatements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return true; - } - - /** - * Return {@code true}, as WebSphere returns wrapped CallableStatements. - */ - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return true; - } - - /** - * Retrieve the Connection via WebSphere's {@code getNativeConnection} method. - */ - @Override - protected Connection doGetNativeConnection(Connection con) throws SQLException { - if (this.webSphereConnectionClass.isAssignableFrom(con.getClass())) { - return (Connection) ReflectionUtils.invokeJdbcMethod(this.webSphereNativeConnectionMethod, null, con); - } - return con; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java deleted file mode 100644 index 172467cb85a..00000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Provides a mechanism for extracting native implementations of JDBC - * interfaces from wrapper objects that got returned from connection pools. - * - *

Can be used independently, for example in custom JDBC access code. - */ -package org.springframework.jdbc.support.nativejdbc; diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java index b7c38059707..3d1220fcabb 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +48,6 @@ import org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedS import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; -import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractorAdapter; import org.springframework.util.LinkedCaseInsensitiveMap; import static org.hamcrest.Matchers.*; @@ -295,19 +293,6 @@ public class JdbcTemplateTests { verify(this.preparedStatement).close(); } - @Test - public void testConnectionCallback() throws Exception { - this.template.setNativeJdbcExtractor(new PlainNativeJdbcExtractor()); - String result = this.template.execute(new ConnectionCallback() { - @Override - public String doInConnection(Connection con) { - assertSame(JdbcTemplateTests.this.connection, con); - return "test"; - } - }); - assertEquals("test", result); - } - @Test public void testConnectionCallbackWithStatementSettings() throws Exception { String result = this.template.execute(new ConnectionCallback() { @@ -317,7 +302,6 @@ public class JdbcTemplateTests { ps.setFetchSize(10); ps.setMaxRows(20); ps.close(); - assertSame(JdbcTemplateTests.this.connection, new PlainNativeJdbcExtractor().getNativeConnection(con)); return "test"; } }); @@ -1096,105 +1080,6 @@ public class JdbcTemplateTests { } } - @Test - public void testNativeJdbcExtractorInvoked() throws Exception { - - final Statement statement2 = mock(Statement.class); - given(statement2.executeQuery(anyString())).willReturn(this.resultSet); - - final PreparedStatement preparedStatement2 = mock(PreparedStatement.class); - given(preparedStatement2.executeQuery()).willReturn(this.resultSet); - - final ResultSet returnResultSet = mock(ResultSet.class); - given(returnResultSet.next()).willReturn(false); - - final CallableStatement callableStatement = mock(CallableStatement.class); - final CallableStatement callableStatement2 = mock(CallableStatement.class); - given(callableStatement2.execute()).willReturn(true); - given(callableStatement2.getUpdateCount()).willReturn(-1); - given(callableStatement2.getResultSet()).willReturn(returnResultSet); - given(callableStatement2.getUpdateCount()).willReturn(-1); - - given(this.connection.createStatement()).willReturn(this.statement); - - this.template.setNativeJdbcExtractor(new NativeJdbcExtractor() { - @Override - public boolean isNativeConnectionNecessaryForNativeStatements() { - return false; - } - @Override - public boolean isNativeConnectionNecessaryForNativePreparedStatements() { - return false; - } - @Override - public boolean isNativeConnectionNecessaryForNativeCallableStatements() { - return false; - } - @Override - public Connection getNativeConnection(Connection con) { - return con; - } - @Override - public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException { - return stmt.getConnection(); - } - @Override - public Statement getNativeStatement(Statement stmt) { - assertTrue(stmt == JdbcTemplateTests.this.statement); - return statement2; - } - @Override - public PreparedStatement getNativePreparedStatement(PreparedStatement ps) { - assertTrue(ps == JdbcTemplateTests.this.preparedStatement); - return preparedStatement2; - } - @Override - public CallableStatement getNativeCallableStatement(CallableStatement cs) { - assertTrue(cs == callableStatement); - return callableStatement2; - } - @Override - public ResultSet getNativeResultSet(ResultSet rs) { - return rs; - } - }); - - this.template.query("my query", new ResultSetExtractor() { - @Override - public Object extractData(ResultSet rs2) { - assertEquals(JdbcTemplateTests.this.resultSet, rs2); - return null; - } - }); - - this.template.query(new PreparedStatementCreator() { - @Override - public PreparedStatement createPreparedStatement(Connection conn) { - return JdbcTemplateTests.this.preparedStatement; - } - }, new ResultSetExtractor() { - @Override - public Object extractData(ResultSet rs2) { - assertEquals(JdbcTemplateTests.this.resultSet, rs2); - return null; - } - }); - - this.template.call(new CallableStatementCreator() { - @Override - public CallableStatement createCallableStatement(Connection con) { - return callableStatement; - } - }, new ArrayList<>()); - - verify(this.resultSet, times(2)).close(); - verify(this.statement).close(); - verify(this.preparedStatement).close(); - verify(returnResultSet).close(); - verify(callableStatement).close(); - verify(this.connection, atLeastOnce()).close(); - } - @Test public void testStaticResultSetClosed() throws Exception { ResultSet resultSet2 = mock(ResultSet.class); @@ -1311,16 +1196,8 @@ public class JdbcTemplateTests { given(this.connection.getMetaData()).willReturn(databaseMetaData); } - private static class PlainNativeJdbcExtractor extends NativeJdbcExtractorAdapter { - - @Override - protected Connection doGetNativeConnection(Connection connection) throws SQLException { - return connection; - } - } - - private static interface JdbcTemplateCallback { + private interface JdbcTemplateCallback { void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch); } @@ -1329,6 +1206,7 @@ public class JdbcTemplateTests { private static class Dispatcher implements PreparedStatementCreator, SqlProvider { private int id; + private String sql; public Dispatcher(int id, String sql) { @@ -1348,4 +1226,5 @@ public class JdbcTemplateTests { return this.sql; } } + } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java index 857c9360294..f527921e9a6 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.java @@ -31,7 +31,6 @@ import org.mockito.InOrder; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.UncategorizedSQLException; -import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; import org.springframework.tests.Assume; import org.springframework.tests.TestGroup; import org.springframework.transaction.CannotCreateTransactionException; @@ -142,7 +141,6 @@ public class DataSourceTransactionManagerTests { try { if (createStatement) { tCon.createStatement(); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(tCon)); } } catch (SQLException ex) { @@ -993,7 +991,6 @@ public class DataSourceTransactionManagerTests { TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } @@ -1027,7 +1024,6 @@ public class DataSourceTransactionManagerTests { final TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } @@ -1042,7 +1038,6 @@ public class DataSourceTransactionManagerTests { assertEquals(con, DataSourceUtils.getConnection(ds)); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } @@ -1088,7 +1083,6 @@ public class DataSourceTransactionManagerTests { dsProxy.setReobtainTransactionalConnections(true); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } @@ -1103,7 +1097,6 @@ public class DataSourceTransactionManagerTests { assertEquals(con, DataSourceUtils.getConnection(ds)); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); - assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java deleted file mode 100644 index 098be6d23a9..00000000000 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2002-2016 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; - -import java.sql.CallableStatement; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.junit.Test; - -import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; - -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; - -/** - * @author Andre Biryukov - * @author Juergen Hoeller - */ -public class NativeJdbcExtractorTests { - - @Test - public void simpleNativeJdbcExtractor() throws SQLException { - SimpleNativeJdbcExtractor extractor = new SimpleNativeJdbcExtractor(); - - Connection con = mock(Connection.class); - DatabaseMetaData dbmd = mock(DatabaseMetaData.class); - Connection con2 = mock(Connection.class); - given(con.getMetaData()).willReturn(dbmd); - given(dbmd.getConnection()).willReturn(con2); - - Connection nativeCon = extractor.getNativeConnection(con); - assertEquals(con2, nativeCon); - - Statement stmt = mock(Statement.class); - given(stmt.getConnection()).willReturn(con); - - nativeCon = extractor.getNativeConnectionFromStatement(stmt); - assertEquals(con2, nativeCon); - - Statement nativeStmt = extractor.getNativeStatement(stmt); - assertEquals(nativeStmt, stmt); - - PreparedStatement ps = mock(PreparedStatement.class); - - PreparedStatement nativePs = extractor.getNativePreparedStatement(ps); - assertEquals(ps, nativePs); - - CallableStatement cs = mock(CallableStatement.class); - ResultSet rs = mock(ResultSet.class); - given(cs.getResultSet()).willReturn(rs); - - CallableStatement nativeCs = extractor.getNativeCallableStatement(cs); - assertEquals(cs, nativeCs); - - ResultSet nativeRs = extractor.getNativeResultSet(cs.getResultSet()); - assertEquals(nativeRs, rs); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java index 5103b0250ef..e37b55aed95 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/JpaDialect.java @@ -145,7 +145,6 @@ public interface JpaDialect extends PersistenceExceptionTranslator { * @see org.springframework.jdbc.datasource.ConnectionHandle#getConnection * @see org.springframework.jdbc.datasource.SimpleConnectionHandle * @see JpaTransactionManager#setDataSource - * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException; diff --git a/src/asciidoc/data-access.adoc b/src/asciidoc/data-access.adoc index 6531bcea0f0..ebba2ae8798 100644 --- a/src/asciidoc/data-access.adoc +++ b/src/asciidoc/data-access.adoc @@ -3222,29 +3222,6 @@ pattern. JTA does not support custom isolation levels! -[[jdbc-NativeJdbcExtractor]] -==== NativeJdbcExtractor -Sometimes you need to access vendor specific JDBC methods that differ from the standard -JDBC API. This can be problematic if you are running in an application server or with a -`DataSource` that wraps the `Connection`, `Statement` and `ResultSet` objects with its -own wrapper objects. To gain access to the native objects you can configure your -`JdbcTemplate` with a `NativeJdbcExtractor`. - -The `NativeJdbcExtractor` comes in a variety of flavors to match your execution -environment: - -* SimpleNativeJdbcExtractor -* C3P0NativeJdbcExtractor -* JBossNativeJdbcExtractor -* WebLogicNativeJdbcExtractor -* WebSphereNativeJdbcExtractor - -Usually the `SimpleNativeJdbcExtractor` is sufficient for unwrapping a `Connection` -object in most environments. See the javadocs for more details. - - - - [[jdbc-advanced-jdbc]] === JDBC batch operations Most JDBC drivers provide improved performance if you batch multiple calls to the same