From 52503cfbaf2b52a1d328dcbe1b5571c6bca56bb3 Mon Sep 17 00:00:00 2001 From: Thomas Risberg Date: Fri, 8 Oct 2010 18:28:01 +0000 Subject: [PATCH] added a nativeJdbcExtractor property for the TableMetaDataProvider and a method to specify the one to use for SImpleJdbcInsert (SPR-7611) git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3717 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../metadata/GenericTableMetaDataProvider.java | 7 +++++++ .../metadata/OracleTableMetaDataProvider.java | 14 +++++++++++++- .../core/metadata/TableMetaDataContext.java | 13 ++++++++++++- .../core/metadata/TableMetaDataProvider.java | 6 ++++++ .../metadata/TableMetaDataProviderFactory.java | 17 +++++++++++++++++ .../jdbc/core/simple/AbstractJdbcInsert.java | 8 ++++++++ .../jdbc/core/simple/SimpleJdbcInsert.java | 6 ++++++ .../core/simple/SimpleJdbcInsertOperations.java | 11 +++++++++++ 8 files changed, 80 insertions(+), 2 deletions(-) diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java index 37ce9949908..a4da76837e8 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * A generic implementation of the {@link TableMetaDataProvider} that should provide enough features for all supported @@ -71,6 +72,9 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** Collection of TableParameterMetaData objects */ private List insertParameterMetaData = new ArrayList(); + /** NativeJdbcExtractor that can be used to retrieve the native connection */ + protected NativeJdbcExtractor nativeJdbcExtractor = null; + /** * Constructor used to initialize with provided database meta data. @@ -147,6 +151,9 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported; } + public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { + this.nativeJdbcExtractor = nativeJdbcExtractor; + } public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java index 408d378ce28..10e9b19c29c 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.java @@ -49,7 +49,19 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException { - Connection con = databaseMetaData.getConnection(); + Connection con = null; + if (nativeJdbcExtractor == null) { + con = databaseMetaData.getConnection(); + if (logger.isDebugEnabled()) { + logger.debug("Using meta data JDBC connection: " + con.getClass().getName()); + } + } + else { + con = nativeJdbcExtractor.getNativeConnection(databaseMetaData.getConnection()); + if (logger.isDebugEnabled()) { + logger.debug("Using native JDBC connection: " + con.getClass().getName()); + } + } Method methodToInvoke = null; Boolean origValueForIncludeSynonyms = null; diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java index 37999a38edb..e4a61662fcc 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java @@ -33,6 +33,7 @@ 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 @@ -70,6 +71,9 @@ public class TableMetaDataContext { /** are we using generated key columns */ private boolean generatedKeyColumnsUsed = false; + /** NativeJdbcExtractor to be used to retrieve the native connection */ + NativeJdbcExtractor nativeJdbcExtractor = null; + /** * Set the name of the table for this context. */ @@ -182,6 +186,13 @@ 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 @@ -190,7 +201,7 @@ public class TableMetaDataContext { * @param generatedKeyNames name of generated keys */ public void processMetaData(DataSource dataSource, List declaredColumns, String[] generatedKeyNames) { - this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this); + this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor); this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java index 1edc0feed1d..d34c6fc11ce 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.java @@ -20,6 +20,8 @@ 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. @@ -127,4 +129,8 @@ public interface TableMetaDataProvider { */ List getTableParameterMetaData(); + /** + * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary + */ + void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java index 4e3ade188f0..63498a6d70c 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.java @@ -28,6 +28,7 @@ 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 based on the type of databse being used. @@ -48,6 +49,19 @@ public class TableMetaDataProviderFactory { */ static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource, final 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 @{link NativeJdbcExtractor} to be used + * @return instance of the TableMetaDataProvider implementation to be used + */ + static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource, + final TableMetaDataContext context, + final NativeJdbcExtractor nativeJdbcExtractor) { try { return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData( dataSource, new DatabaseMetaDataCallback() { @@ -74,6 +88,9 @@ public class TableMetaDataProviderFactory { else { provider = new GenericTableMetaDataProvider(databaseMetaData); } + if (nativeJdbcExtractor != null) { + provider.setNativeJdbcExtractor(nativeJdbcExtractor); + } if (logger.isDebugEnabled()) { logger.debug("Using " + provider.getClass().getName()); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java index aef3a3a962e..af1db24ab41 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java @@ -48,6 +48,7 @@ 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; /** @@ -227,6 +228,13 @@ public abstract class AbstractJdbcInsert { return jdbcTemplate; } + /** + * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary + */ + public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { + this.tableMetaDataContext.setNativeJdbcExtractor(nativeJdbcExtractor); + } + //------------------------------------------------------------------------- // Methods handling compilation issues diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java index 6192f006e08..20814d8501c 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.java @@ -24,6 +24,7 @@ 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 @@ -104,6 +105,11 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn return this; } + public SimpleJdbcInsertOperations useNativeJdbcExtractorForMetaData(NativeJdbcExtractor nativeJdbcExtractor) { + setNativeJdbcExtractor(nativeJdbcExtractor); + return this; + } + public int execute(Map args) { return doExecute(args); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java index b51a615ffbb..a4351abadc4 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.java @@ -20,6 +20,7 @@ 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}. @@ -81,6 +82,16 @@ 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.