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 a4da76837e..3cd3e5109f 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,8 @@ 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 - * databases. + * A generic implementation of the {@link TableMetaDataProvider} that should provide + * enough features for all supported databases. * * @author Thomas Risberg * @since 2.5 @@ -67,30 +67,23 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** database products we know not supporting the use of a String[] for generated keys */ private List productsNotSupportingGeneratedKeysColumnNameArray = - Arrays.asList(new String[] {"Apache Derby", "HSQL Database Engine"}); + Arrays.asList("Apache Derby", "HSQL Database Engine"); /** Collection of TableParameterMetaData objects */ private List insertParameterMetaData = new ArrayList(); /** NativeJdbcExtractor that can be used to retrieve the native connection */ - protected NativeJdbcExtractor nativeJdbcExtractor = null; + private NativeJdbcExtractor nativeJdbcExtractor; /** * Constructor used to initialize with provided database meta data. * @param databaseMetaData meta data to be used - * @throws SQLException */ protected GenericTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { - userName = databaseMetaData.getUserName(); + this.userName = databaseMetaData.getUserName(); } - /** - * Get whether identifiers use upper case - */ - public boolean isStoresUpperCaseIdentifiers() { - return storesUpperCaseIdentifiers; - } /** * Specify whether identifiers use upper case @@ -100,29 +93,36 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } /** - * Get whether identifiers use lower case + * Get whether identifiers use upper case */ - public boolean isStoresLowerCaseIdentifiers() { - return storesLowerCaseIdentifiers; + public boolean isStoresUpperCaseIdentifiers() { + return this.storesUpperCaseIdentifiers; } /** - * Specify whether identifiers use lower case + * Specify whether identifiers use lower case. */ public void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) { this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers; } + /** + * Get whether identifiers use lower case + */ + public boolean isStoresLowerCaseIdentifiers() { + return this.storesLowerCaseIdentifiers; + } + public boolean isTableColumnMetaDataUsed() { - return tableColumnMetaDataUsed; + return this.tableColumnMetaDataUsed; } public List getTableParameterMetaData() { - return insertParameterMetaData; + return this.insertParameterMetaData; } public boolean isGetGeneratedKeysSupported() { - return getGeneratedKeysSupported; + return this.getGeneratedKeysSupported; } public boolean isGetGeneratedKeysSimulated(){ @@ -140,10 +140,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { this.getGeneratedKeysSupported = getGeneratedKeysSupported; } - public boolean isGeneratedKeysColumnNameArraySupported() { - return generatedKeysColumnNameArraySupported; - } - /** * Specify whether a column name array is supported for generated keys */ @@ -151,12 +147,20 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported; } + public boolean isGeneratedKeysColumnNameArraySupported() { + return this.generatedKeysColumnNameArraySupported; + } + public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } - public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { + protected NativeJdbcExtractor getNativeJdbcExtractor() { + return this.nativeJdbcExtractor; + } + + public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { try { if (databaseMetaData.supportsGetGeneratedKeys()) { logger.debug("GetGeneratedKeys is supported"); @@ -172,7 +176,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } try { String databaseProductName = databaseMetaData.getDatabaseProductName(); - if (productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) { + if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) { logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName); setGeneratedKeysColumnNameArraySupported(false); } @@ -185,7 +189,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + se.getMessage()); } try { - databaseVersion = databaseMetaData.getDatabaseProductVersion(); + this.databaseVersion = databaseMetaData.getDatabaseProductVersion(); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + se.getMessage()); @@ -205,47 +209,56 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } - public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) - throws SQLException { - - tableColumnMetaDataUsed = true; + public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, + String schemaName, String tableName) throws SQLException { + this.tableColumnMetaDataUsed = true; locateTableAndProcessMetaData(databaseMetaData, catalogName, schemaName, tableName); - - } public String tableNameToUse(String tableName) { - if (tableName == null) + if (tableName == null) { return null; - else if (isStoresUpperCaseIdentifiers()) + } + else if (isStoresUpperCaseIdentifiers()) { return tableName.toUpperCase(); - else if(isStoresLowerCaseIdentifiers()) + } + else if(isStoresLowerCaseIdentifiers()) { return tableName.toLowerCase(); - else + } + else { return tableName; + } } public String catalogNameToUse(String catalogName) { - if (catalogName == null) + if (catalogName == null) { return null; - else if (isStoresUpperCaseIdentifiers()) + } + else if (isStoresUpperCaseIdentifiers()) { return catalogName.toUpperCase(); - else if(isStoresLowerCaseIdentifiers()) + } + else if(isStoresLowerCaseIdentifiers()) { return catalogName.toLowerCase(); - else - return catalogName; + } + else { + return catalogName; + } } public String schemaNameToUse(String schemaName) { - if (schemaName == null) + if (schemaName == null) { return null; - else if (isStoresUpperCaseIdentifiers()) + } + else if (isStoresUpperCaseIdentifiers()) { return schemaName.toUpperCase(); - else if(isStoresLowerCaseIdentifiers()) + } + else if(isStoresLowerCaseIdentifiers()) { return schemaName.toLowerCase(); - else - return schemaName; + } + else { + return schemaName; + } } public String metaDataCatalogNameToUse(String catalogName) { @@ -261,19 +274,20 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** - * Provide access to version info for subclasses + * Provide access to version info for subclasses. */ protected String getDatabaseVersion() { - return databaseVersion; + return this.databaseVersion; } /** - * Method supporting the metedata processing for a table + * Method supporting the metedata processing for a table. */ - private void locateTableAndProcessMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) { + private void locateTableAndProcessMetaData(DatabaseMetaData databaseMetaData, String catalogName, + String schemaName, String tableName) { + Map tableMeta = new HashMap(); ResultSet tables = null; - try { tables = databaseMetaData.getTables( catalogNameToUse(catalogName), @@ -311,7 +325,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided"); } else { - TableMetaData tmd = null; + TableMetaData tmd; if (schemaName == null) { tmd = tableMeta.get(userName.toUpperCase()); if (tmd == null) { @@ -320,14 +334,16 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { tmd = tableMeta.get("DBO"); } if (tmd == null) { - throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the default schema"); + throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + + tableName + "' in the default schema"); } } } else { tmd = tableMeta.get(schemaName.toUpperCase()); if (tmd == null) { - throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the '" + schemaName + "' schema"); + throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + + tableName + "' in the '" + schemaName + "' schema"); } } @@ -378,7 +394,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { dataType, nullable ); - insertParameterMetaData.add(meta); + this.insertParameterMetaData.add(meta); if (logger.isDebugEnabled()) { logger.debug("Retrieved metadata: " + meta.getParameterName() + @@ -389,7 +405,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } } catch (SQLException se) { - logger.warn("Error while retreiving metadata for table columns: " + se.getMessage()); + logger.warn("Error while retrieving metadata for table columns: " + se.getMessage()); } finally { try { @@ -397,7 +413,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { tableColumns.close(); } catch (SQLException se) { - logger.warn("Problem closing resultset for table column metadata " + se.getMessage()); + logger.warn("Problem closing ResultSet for table column metadata " + se.getMessage()); } } @@ -405,45 +421,49 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** - * Class representing table meta data + * Inner class representing table meta data. */ - private class TableMetaData { + private static class TableMetaData { + private String catalogName; + private String schemaName; + private String tableName; + private String type; - - public String getCatalogName() { - return catalogName; - } - public void setCatalogName(String catalogName) { this.catalogName = catalogName; } - public String getSchemaName() { - return schemaName; + public String getCatalogName() { + return this.catalogName; } public void setSchemaName(String schemaName) { this.schemaName = schemaName; } - public String getTableName() { - return tableName; + public String getSchemaName() { + return this.schemaName; } public void setTableName(String tableName) { this.tableName = tableName; } - public String getType() { - return type; + public String getTableName() { + return this.tableName; } public void setType(String type) { this.type = type; } + + public String getType() { + return this.type; + } } + } 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 10e9b19c29..afaf351587 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,17 +22,20 @@ import java.sql.DatabaseMetaData; import java.sql.SQLException; import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; +import org.springframework.util.ReflectionUtils; /** - * The Oracle specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. + * Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * Supports a feature for including synonyms in the metadata lookup. * * @author Thomas Risberg + * @author Juergen Hoeller * @since 3.0 */ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { - private boolean includeSynonyms; + private final boolean includeSynonyms; public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { @@ -49,67 +52,61 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException { - 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; - - if (includeSynonyms) { - if (con.getClass().getName().startsWith("oracle")) { - if (logger.isDebugEnabled()) { - logger.debug("Including synonyms in table metadata lookup."); - } - } - else { - logger.warn("Unable to include synonyms in table metadata lookup. Connection used for " + - "DatabaseMetaData is not recognized as an Oracle connection; " + - "class is " + con.getClass().getName()); - } - - } - else { - if (logger.isDebugEnabled()) { - logger.debug("Defaulting to no synonyms in table metadata lookup."); - } + if (!this.includeSynonyms) { + logger.debug("Defaulting to no synonyms in table metadata lookup"); + super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); + return; } - if (includeSynonyms && con.getClass().getName().startsWith("oracle")) { - try { - methodToInvoke = con.getClass().getMethod("getIncludeSynonyms", (Class[]) null); - methodToInvoke.setAccessible(true); - origValueForIncludeSynonyms = (Boolean)methodToInvoke.invoke(con); - methodToInvoke = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class}); - methodToInvoke.setAccessible(true); - methodToInvoke.invoke(con, Boolean.TRUE); - } - catch (Exception ex) { - throw new InvalidDataAccessApiUsageException( - "Couldn't initialize Oracle Connection.", ex); - } - + Connection con = databaseMetaData.getConnection(); + NativeJdbcExtractor nativeJdbcExtractor = getNativeJdbcExtractor(); + if (nativeJdbcExtractor != null) { + con = nativeJdbcExtractor.getNativeConnection(con); } + boolean isOracleCon; + try { + Class oracleConClass = getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection"); + isOracleCon = oracleConClass.isInstance(con); + } + catch (ClassNotFoundException ex) { + if (logger.isInfoEnabled()) { + logger.info("Couldn't find Oracle JDBC API: " + ex); + } + isOracleCon = false; + } + + if (!isOracleCon) { + logger.warn("Unable to include synonyms in table metadata lookup. Connection used for " + + "DatabaseMetaData is not recognized as an Oracle connection: " + con); + super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); + return; + } + + logger.debug("Including synonyms in table metadata lookup"); + Method setIncludeSynonyms; + Boolean originalValueForIncludeSynonyms; + + try { + Method getIncludeSynonyms = con.getClass().getMethod("getIncludeSynonyms", (Class[]) null); + ReflectionUtils.makeAccessible(getIncludeSynonyms); + originalValueForIncludeSynonyms = (Boolean) getIncludeSynonyms.invoke(con); + + setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class}); + ReflectionUtils.makeAccessible(setIncludeSynonyms); + setIncludeSynonyms.invoke(con, Boolean.TRUE); + } + catch (Exception ex) { + throw new InvalidDataAccessApiUsageException("Couldn't prepare Oracle Connection", ex); + } + super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); - if (includeSynonyms && con.getClass().getName().startsWith("oracle")) { - try { - methodToInvoke = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class}); - methodToInvoke.setAccessible(true); - methodToInvoke.invoke(con, origValueForIncludeSynonyms); - } - catch (Exception ex) { - throw new InvalidDataAccessApiUsageException( - "Couldn't restore Oracle Connection.", ex); - } + + try { + setIncludeSynonyms.invoke(con, originalValueForIncludeSynonyms); + } + catch (Exception ex) { + throw new InvalidDataAccessApiUsageException("Couldn't reset Oracle Connection", ex); } } -} \ No newline at end of file + +} 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 e4a61662fc..31f73add5f 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 @@ -72,7 +72,8 @@ public class TableMetaDataContext { private boolean generatedKeyColumnsUsed = false; /** NativeJdbcExtractor to be used to retrieve the native connection */ - NativeJdbcExtractor nativeJdbcExtractor = null; + NativeJdbcExtractor nativeJdbcExtractor; + /** * Set the name of the table for this context. @@ -162,7 +163,7 @@ public class TableMetaDataContext { /** * Does this database support simple query to retrieve generated keys - * when the JDBC 3.0 feature is not supported + * when the JDBC 3.0 feature is not supported. * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ public boolean isGetGeneratedKeysSimulated() { @@ -171,7 +172,7 @@ public class TableMetaDataContext { /** * Does this database support simple query to retrieve generated keys - * when the JDBC 3.0 feature is not supported + * when the JDBC 3.0 feature is not supported. * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) { @@ -179,7 +180,7 @@ public class TableMetaDataContext { } /** - * Is a column name String array for retrieving generated keys supported + * Is a column name String array for retrieving generated keys supported? * {@link java.sql.Connection#createStruct(String, Object[])}? */ public boolean isGeneratedKeysColumnNameArraySupported() { @@ -187,7 +188,7 @@ public class TableMetaDataContext { } /** - * Set {@link NativeJdbcExtractor} to be used to retrieve the native connection + * Set {@link NativeJdbcExtractor} to be used to retrieve the native connection. */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; @@ -195,7 +196,7 @@ public class TableMetaDataContext { /** - * Process the current meta data with the provided configuration options + * Process the current meta data with the provided configuration options. * @param dataSource the DataSource being used * @param declaredColumns any columns that are declared * @param generatedKeyNames name of generated keys @@ -212,7 +213,7 @@ public class TableMetaDataContext { */ protected List reconcileColumnsToUse(List declaredColumns, String[] generatedKeyNames) { if (generatedKeyNames.length > 0) { - generatedKeyColumnsUsed = true; + this.generatedKeyColumnsUsed = true; } if (declaredColumns.size() > 0) { return new ArrayList(declaredColumns); @@ -240,7 +241,7 @@ public class TableMetaDataContext { // database metadata is not necessarily providing case sensitive column names Map caseInsensitiveParameterNames = SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource); - for (String column : tableColumns) { + for (String column : this.tableColumns) { if (parameterSource.hasValue(column)) { values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column)); } @@ -280,7 +281,7 @@ public class TableMetaDataContext { for (String key : inParameters.keySet()) { source.put(key.toLowerCase(), inParameters.get(key)); } - for (String column : tableColumns) { + for (String column : this.tableColumns) { values.add(source.get(column.toLowerCase())); } return values; @@ -316,7 +317,7 @@ public class TableMetaDataContext { } insertStatement.append(") VALUES("); if (columnCount < 1) { - if (generatedKeyColumnsUsed) { + if (this.generatedKeyColumnsUsed) { logger.info("Unable to locate non-key columns for table '" + this.getTableName() + "' so an empty insert statement is generated"); } @@ -340,15 +341,12 @@ public class TableMetaDataContext { * @return the array of types to be used */ public int[] createInsertTypes() { - int[] types = new int[this.getTableColumns().size()]; - List parameters = this.metaDataProvider.getTableParameterMetaData(); Map parameterMap = new HashMap(parameters.size()); for (TableParameterMetaData tpmd : parameters) { parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd); } - int typeIndx = 0; for (String column : this.getTableColumns()) { if (column == null) { @@ -365,7 +363,6 @@ public class TableMetaDataContext { } typeIndx++; } - return types; } 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 63498a6d70..15421a998a 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2010 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. @@ -18,7 +18,6 @@ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; - import javax.sql.DataSource; import org.apache.commons.logging.Log; @@ -38,74 +37,70 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; */ public class TableMetaDataProviderFactory { - /** Logger */ private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class); + /** * Create a TableMetaDataProvider based on the database metedata * @param dataSource used to retrieve metedata * @param context the class that holds configuration and metedata * @return instance of the TableMetaDataProvider implementation to be used */ - static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource, - final TableMetaDataContext context) { + 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 @{link NativeJdbcExtractor} to be used + * @param nativeJdbcExtractor the 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) { + public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, + final TableMetaDataContext context, final NativeJdbcExtractor nativeJdbcExtractor) { try { - return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData( - dataSource, new DatabaseMetaDataCallback() { - - public Object processMetaData(DatabaseMetaData databaseMetaData) - throws SQLException, MetaDataAccessException { - String databaseProductName = - JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); - boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData(); - TableMetaDataProvider provider; - if ("Oracle".equals(databaseProductName)) { - provider = new OracleTableMetaDataProvider(databaseMetaData, - context.isOverrideIncludeSynonymsDefault()); - } - else if ("HSQL Database Engine".equals(databaseProductName)) { - provider = new HsqlTableMetaDataProvider(databaseMetaData); - } - else if ("PostgreSQL".equals(databaseProductName)) { - provider = new PostgresTableMetaDataProvider(databaseMetaData); - } - else if ("Apache Derby".equals(databaseProductName)) { - provider = new DerbyTableMetaDataProvider(databaseMetaData); - } - else { - provider = new GenericTableMetaDataProvider(databaseMetaData); - } - if (nativeJdbcExtractor != null) { - provider.setNativeJdbcExtractor(nativeJdbcExtractor); - } - if (logger.isDebugEnabled()) { - logger.debug("Using " + provider.getClass().getName()); - } - provider.initializeWithMetaData(databaseMetaData); - if (accessTableColumnMetaData) { - provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(), - context.getSchemaName(), context.getTableName()); - } - return provider; - } - }); - } catch (MetaDataAccessException e) { - throw new DataAccessResourceFailureException("Error retreiving database metadata", e); + return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, + new DatabaseMetaDataCallback() { + public Object processMetaData(DatabaseMetaData databaseMetaData) throws SQLException { + String databaseProductName = + JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); + boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData(); + TableMetaDataProvider provider; + if ("Oracle".equals(databaseProductName)) { + provider = new OracleTableMetaDataProvider(databaseMetaData, + context.isOverrideIncludeSynonymsDefault()); + } + else if ("HSQL Database Engine".equals(databaseProductName)) { + provider = new HsqlTableMetaDataProvider(databaseMetaData); + } + else if ("PostgreSQL".equals(databaseProductName)) { + provider = new PostgresTableMetaDataProvider(databaseMetaData); + } + else if ("Apache Derby".equals(databaseProductName)) { + provider = new DerbyTableMetaDataProvider(databaseMetaData); + } + else { + provider = new GenericTableMetaDataProvider(databaseMetaData); + } + if (nativeJdbcExtractor != null) { + provider.setNativeJdbcExtractor(nativeJdbcExtractor); + } + if (logger.isDebugEnabled()) { + logger.debug("Using " + provider.getClass().getSimpleName()); + } + provider.initializeWithMetaData(databaseMetaData); + if (accessTableColumnMetaData) { + provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(), + context.getSchemaName(), context.getTableName()); + } + return provider; + } + }); + } + catch (MetaDataAccessException ex) { + throw new DataAccessResourceFailureException("Error retrieving database metadata", ex); } - } } 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 af1db24ab4..018892ba3a 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2010 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. @@ -18,25 +18,24 @@ package org.springframework.jdbc.core.simple; import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.sql.ResultSet; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.core.JdbcTemplate; @@ -57,6 +56,7 @@ import org.springframework.util.Assert; * This class provides the base SPI for {@link SimpleJdbcInsert}. * * @author Thomas Risberg + * @author Juergen Hoeller * @since 2.5 */ public abstract class AbstractJdbcInsert { @@ -65,10 +65,13 @@ public abstract class AbstractJdbcInsert { protected final Log logger = LogFactory.getLog(getClass()); /** Lower-level class used to execute SQL */ - private JdbcTemplate jdbcTemplate = new JdbcTemplate(); + private final JdbcTemplate jdbcTemplate; + + /** Context used to retrieve and manage database metadata */ + private final TableMetaDataContext tableMetaDataContext = new TableMetaDataContext(); /** List of columns objects to be used in insert statement */ - private List declaredColumns = new ArrayList(); + private final List declaredColumns = new ArrayList(); /** * Has this operation been compiled? Compilation means at @@ -77,31 +80,30 @@ public abstract class AbstractJdbcInsert { */ private boolean compiled = false; - /** the generated string used for insert statement */ + /** The generated string used for insert statement */ private String insertString; - /** the SQL Type information for the insert columns */ + /** The SQL type information for the insert columns */ private int[] insertTypes; - /** the names of the columns holding the generated key */ - private String[] generatedKeyNames = new String[] {}; - - /** context used to retrieve and manage database metadata */ - private TableMetaDataContext tableMetaDataContext = new TableMetaDataContext(); + /** The names of the columns holding the generated key */ + private String[] generatedKeyNames = new String[0]; /** * Constructor for sublasses to delegate to for setting the DataSource. */ protected AbstractJdbcInsert(DataSource dataSource) { - jdbcTemplate = new JdbcTemplate(dataSource); + this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * Constructor for sublasses to delegate to for setting the JdbcTemplate. */ protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) { + Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); this.jdbcTemplate = jdbcTemplate; + setNativeJdbcExtractor(jdbcTemplate.getNativeJdbcExtractor()); } @@ -109,26 +111,19 @@ public abstract class AbstractJdbcInsert { // Methods dealing with configuaration properties //------------------------------------------------------------------------- - /** - * Get the name of the table for this insert - */ - public String getTableName() { - return tableMetaDataContext.getTableName(); - } - /** * Set the name of the table for this insert */ public void setTableName(String tableName) { checkIfConfigurationModificationIsAllowed(); - tableMetaDataContext.setTableName(tableName); + this.tableMetaDataContext.setTableName(tableName); } /** - * Get the name of the schema for this insert + * Get the name of the table for this insert */ - public String getSchemaName() { - return tableMetaDataContext.getSchemaName(); + public String getTableName() { + return this.tableMetaDataContext.getTableName(); } /** @@ -136,14 +131,14 @@ public abstract class AbstractJdbcInsert { */ public void setSchemaName(String schemaName) { checkIfConfigurationModificationIsAllowed(); - tableMetaDataContext.setSchemaName(schemaName); + this.tableMetaDataContext.setSchemaName(schemaName); } /** - * Get the name of the catalog for this insert + * Get the name of the schema for this insert */ - public String getCatalogName() { - return tableMetaDataContext.getCatalogName(); + public String getSchemaName() { + return this.tableMetaDataContext.getSchemaName(); } /** @@ -151,7 +146,14 @@ public abstract class AbstractJdbcInsert { */ public void setCatalogName(String catalogName) { checkIfConfigurationModificationIsAllowed(); - tableMetaDataContext.setCatalogName(catalogName); + this.tableMetaDataContext.setCatalogName(catalogName); + } + + /** + * Get the name of the catalog for this insert + */ + public String getCatalogName() { + return this.tableMetaDataContext.getCatalogName(); } /** @@ -159,22 +161,22 @@ public abstract class AbstractJdbcInsert { */ public void setColumnNames(List columnNames) { checkIfConfigurationModificationIsAllowed(); - declaredColumns.clear(); - declaredColumns.addAll(columnNames); + this.declaredColumns.clear(); + this.declaredColumns.addAll(columnNames); } /** * Get the names of the columns used */ public List getColumnNames() { - return Collections.unmodifiableList(declaredColumns); + return Collections.unmodifiableList(this.declaredColumns); } /** * Get the names of any generated keys */ public String[] getGeneratedKeyNames() { - return generatedKeyNames; + return this.generatedKeyNames; } /** @@ -207,32 +209,32 @@ 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 */ public String getInsertString() { - return insertString; + return this.insertString; } /** * Get the array of {@link java.sql.Types} to be used for insert */ public int[] getInsertTypes() { - return insertTypes; + return this.insertTypes; } /** * Get the {@link JdbcTemplate} that is configured to be used */ protected JdbcTemplate getJdbcTemplate() { - return jdbcTemplate; - } - - /** - * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary - */ - public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { - this.tableMetaDataContext.setNativeJdbcExtractor(nativeJdbcExtractor); + return this.jdbcTemplate; }