Drop NativeJdbcExtractor mechanism in favor of JDBC 4 unwrap
Issue: SPR-14670
This commit is contained in:
parent
54f01cffaf
commit
07dd61eabd
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
|
@ -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<String>() {
|
||||
@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<String>() {
|
||||
|
@ -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<Object>() {
|
||||
@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<Object>() {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue