Drop NativeJdbcExtractor mechanism in favor of JDBC 4 unwrap

Issue: SPR-14670
This commit is contained in:
Juergen Hoeller
2017-02-15 18:04:08 +01:00
parent 54f01cffaf
commit 07dd61eabd
36 changed files with 124 additions and 1693 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}
}

View File

@@ -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: <i>any</i> 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.
* <p>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<String, Object> 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);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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;
}
}

View File

@@ -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()

View File

@@ -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> 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) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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}.
*
* <p>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);
con = (Connection) con.unwrap(oracleConClass);
}
catch (ClassNotFoundException ex) {
if (logger.isInfoEnabled()) {
logger.info("Couldn't find Oracle JDBC API: " + ex);
}
isOracleCon = false;
}
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);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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<String> declaredColumns, String[] generatedKeyNames) {
this.metaDataProvider =
TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor);
this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames);
}

View File

@@ -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<TableParameterMetaData> getTableParameterMetaData();
/**
* Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary
*/
void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -317,7 +317,6 @@ public abstract class AbstractJdbcCall {
this.callableStatementFactory =
new CallableStatementCreatorFactory(getCallString(), this.callMetaDataContext.getCallParameters());
this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor());
onCompileInternal();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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<String, ?> args) {
return doExecute(args);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import java.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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,10 +23,8 @@ import java.sql.Connection;
* Connection proxies. Allows access to the underlying target Connection.
*
* <p>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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,11 +68,8 @@ import org.springframework.core.Constants;
*
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections
* (which implement the {@link ConnectionProxy} interface) in order to handle
* lazy fetching of an actual JDBC Connection. Therefore, the returned Connections
* cannot be cast to a native JDBC Connection type such as OracleConnection or
* to a connection pool implementation type. Use a corresponding
* {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}
* or JDBC 4's {@link Connection#unwrap} to retrieve the native JDBC Connection.
* lazy fetching of an actual JDBC Connection. Use {@link Connection#unwrap}
* to retrieve the native JDBC Connection.
*
* @author Juergen Hoeller
* @since 1.1.4

View File

@@ -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;
* <p>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.
*
* <p>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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,13 +61,9 @@ import org.springframework.util.Assert;
* that all operations performed through standard JDBC will automatically participate
* in Spring-managed transaction timeouts.
*
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections
* (which implement the {@link ConnectionProxy} interface) in order to handle
* close calls properly. Therefore, the returned Connections cannot be cast
* to a native JDBC Connection type 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.
* <p><b>NOTE:</b> This DataSource proxy needs to return wrapped Connections (which
* implement the {@link ConnectionProxy} interface) in order to handle close calls
* properly. Use {@link Connection#unwrap} to retrieve the native JDBC Connection.
*
* @author Juergen Hoeller
* @since 1.1

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -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();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,6 @@ public abstract class SqlOperation extends RdbmsOperation {
if (getGeneratedKeysColumnNames() != null) {
this.preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames());
}
this.preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor());
onCompileInternal();
}

View File

@@ -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) {

View File

@@ -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.
*
* <p>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}.
*
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working with
* a C3P0 DataSource: If a given object is not a C3P0 wrapper, it will be
* returned as-is.
*
* <p>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;
}
}

View File

@@ -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.
*
* <p>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}.
*
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> 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;
}
}

View File

@@ -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.
*
* <p>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<? extends Connection> connectionType = Connection.class;
private Class<? extends Statement> statementType = Statement.class;
private Class<? extends PreparedStatement> preparedStatementType = PreparedStatement.class;
private Class<? extends CallableStatement> callableStatementType = CallableStatement.class;
private Class<? extends ResultSet> resultSetType = ResultSet.class;
/**
* Set the vendor's Connection type, e.g. {@code oracle.jdbc.OracleConnection}.
*/
public void setConnectionType(Class<? extends Connection> connectionType) {
this.connectionType = connectionType;
}
/**
* Set the vendor's Statement type, e.g. {@code oracle.jdbc.OracleStatement}.
*/
public void setStatementType(Class<? extends Statement> statementType) {
this.statementType = statementType;
}
/**
* Set the vendor's PreparedStatement type, e.g. {@code oracle.jdbc.OraclePreparedStatement}.
*/
public void setPreparedStatementType(Class<? extends PreparedStatement> preparedStatementType) {
this.preparedStatementType = preparedStatementType;
}
/**
* Set the vendor's CallableStatement type, e.g. {@code oracle.jdbc.OracleCallableStatement}.
*/
public void setCallableStatementType(Class<? extends CallableStatement> callableStatementType) {
this.callableStatementType = callableStatementType;
}
/**
* Set the vendor's ResultSet type, e.g. {@code oracle.jdbc.OracleResultSet}.
*/
public void setResultSetType(Class<? extends ResultSet> 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);
}
}

View File

@@ -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.
*
* <p>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.
*
* <p>Note: To be able to support any pool's strategy of native ResultSet wrapping,
* it is advisable to get both the native Statement <i>and</i> 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
* <i>not</i> necessary to unwrap the Connection to retrieve a native ResultSet.
*
* <p>When working with a simple connection pool that wraps Connections but not
* Statements, a {@link SimpleNativeJdbcExtractor} is often sufficient.
*
* <p>{@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.
* <p>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.
* <p>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.
* <p>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.
* <p>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;
}

View File

@@ -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.
*
* <p>{@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.
*
* <p>{@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()}.
*
* <p>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.
* <p>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;
}
}

View File

@@ -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:
* <ul>
* <li>{@code oracle.jdbc.OracleConnection}
* <li>{@code oracle.jdbc.OracleStatement}
* <li>{@code oracle.jdbc.OraclePreparedStatement}
* <li>{@code oracle.jdbc.OracleCallableStatement}
* <li>{@code oracle.jdbc.OracleResultSet}
* </ul>
*
* <p>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<Connection>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection"));
setStatementType((Class<Statement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement"));
setPreparedStatementType((Class<PreparedStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement"));
setCallableStatementType((Class<CallableStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement"));
setResultSetType((Class<ResultSet>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet"));
}
catch (Exception ex) {
throw new IllegalStateException(
"Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex);
}
}
}

View File

@@ -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.
*
* <p>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()}.
*
* <p>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.
*
* <p>For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping:
* <ul>
* <li>Use a default SimpleNativeJdbcExtractor for Resin and SJSAS (no JDBC
* Statement objects are wrapped, therefore no special unwrapping is necessary).
* <li>Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx"
* flags set to "true" for C3P0 (all JDBC Statement objects are wrapped,
* but none of the wrappers allow for unwrapping).
* <li>Use a JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are
* wrapped, but all of them can be extracted by casting to implementation classes).
* </ul>
*
* @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.
* <p>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.
* <p>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.
* <p>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.
* <p>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.
* <p>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.
* <p>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;
}
}

View File

@@ -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.
*
* <p>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}.
*
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> 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;
}
}

View File

@@ -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.
*
* <p>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}.
*
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> 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;
}
}

View File

@@ -1,7 +0,0 @@
/**
* Provides a mechanism for extracting native implementations of JDBC
* interfaces from wrapper objects that got returned from connection pools.
*
* <p>Can be used independently, for example in custom JDBC access code.
*/
package org.springframework.jdbc.support.nativejdbc;