From de4349792b56254476f513a40948aaa998308cf2 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 12 Jan 2017 21:15:08 +0100 Subject: [PATCH] GenericTableMetaDataProvider falls back to single schema as default Issue: SPR-15090 --- .../GenericTableMetaDataProvider.java | 143 ++++++++++-------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java index 14176972c0..6e6586946f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.java @@ -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,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.JdbcUtils; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** @@ -37,6 +38,7 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; * enough features for all supported databases. * * @author Thomas Risberg + * @author Juergen Hoeller * @since 2.5 */ public class GenericTableMetaDataProvider implements TableMetaDataProvider { @@ -163,17 +165,23 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } } catch (SQLException ex) { - logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys' - " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys': " + ex.getMessage()); + } } try { String databaseProductName = databaseMetaData.getDatabaseProductName(); if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) { - logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName); + if (logger.isDebugEnabled()) { + logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName); + } setGeneratedKeysColumnNameArraySupported(false); } else { if (isGetGeneratedKeysSupported()) { - logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName); + if (logger.isDebugEnabled()) { + logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName); + } setGeneratedKeysColumnNameArraySupported(true); } else { @@ -182,25 +190,36 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } } catch (SQLException ex) { - logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName': " + ex.getMessage()); + } } + try { this.databaseVersion = databaseMetaData.getDatabaseProductVersion(); } catch (SQLException ex) { - logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion': " + ex.getMessage()); + } } + try { setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers()); } catch (SQLException ex) { - logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers': " + ex.getMessage()); + } } + try { setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers()); } catch (SQLException ex) { - logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers': " + ex.getMessage()); + } } } @@ -278,7 +297,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { * Provide access to default schema for subclasses. */ protected String getDefaultSchema() { - return userName; + return this.userName; } /** @@ -291,17 +310,14 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** * 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), - schemaNameToUse(schemaName), - tableNameToUse(tableName), - null); + catalogNameToUse(catalogName), schemaNameToUse(schemaName), tableNameToUse(tableName), null); while (tables != null && tables.next()) { TableMetaData tmd = new TableMetaData(); tmd.setCatalogName(tables.getString("TABLE_CAT")); @@ -316,49 +332,52 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { } } catch (SQLException ex) { - logger.warn("Error while accessing table meta data results" + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error while accessing table meta data results: " + ex.getMessage()); + } } finally { - if (tables != null) { - try { - tables.close(); - } - catch (SQLException ex) { - logger.warn("Error while closing table meta data results" + ex.getMessage()); - } - } + JdbcUtils.closeResultSet(tables); } - if (tableMeta.size() < 1) { - logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided"); + if (tableMeta.isEmpty()) { + if (logger.isWarnEnabled()) { + logger.warn("Unable to locate table meta data for '" + tableName + "': column names must be provided"); + } } else { - TableMetaData tmd; - if (schemaName == null) { - tmd = tableMeta.get(getDefaultSchema()); - if (tmd == null) { - tmd = tableMeta.get(userName != null ? userName.toUpperCase() : ""); - } - if (tmd == null) { - tmd = tableMeta.get("PUBLIC"); - } - if (tmd == null) { - tmd = tableMeta.get("DBO"); - } - if (tmd == null) { - 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"); - } - } + processTableColumns(databaseMetaData, findTableMetaData(schemaName, tableName, tableMeta)); + } + } - processTableColumns(databaseMetaData, tmd); + private TableMetaData findTableMetaData(String schemaName, String tableName, Map tableMeta) { + if (schemaName != null) { + TableMetaData tmd = tableMeta.get(schemaName.toUpperCase()); + if (tmd == null) { + throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + + tableName + "' in the '" + schemaName + "' schema"); + } + return tmd; + } + else if (tableMeta.size() == 1) { + return tableMeta.values().iterator().next(); + } + else { + TableMetaData tmd = tableMeta.get(getDefaultSchema()); + if (tmd == null) { + tmd = tableMeta.get(this.userName != null ? this.userName.toUpperCase() : ""); + } + if (tmd == null) { + tmd = tableMeta.get("PUBLIC"); + } + if (tmd == null) { + tmd = tableMeta.get("DBO"); + } + if (tmd == null) { + throw new DataAccessResourceFailureException( + "Unable to locate table meta data for '" + tableName + "' in the default schema"); + } + return tmd; } } @@ -389,10 +408,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { if ("NUMBER".equals(typeName) && decimalDigits == 0) { dataType = Types.NUMERIC; if (logger.isDebugEnabled()) { - logger.debug("Overriding metadata: " - + columnName + - " now using NUMERIC instead of DECIMAL" - ); + logger.debug("Overriding metadata: " + columnName + " now NUMERIC instead of DECIMAL"); } } } @@ -400,24 +416,19 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider { TableParameterMetaData meta = new TableParameterMetaData(columnName, dataType, nullable); this.tableParameterMetaData.add(meta); if (logger.isDebugEnabled()) { - logger.debug("Retrieved metadata: " + meta.getParameterName() + - " " + meta.getSqlType() + " " + meta.isNullable()); + logger.debug("Retrieved metadata: " + meta.getParameterName() + " " + + meta.getSqlType() + " " + meta.isNullable()); } } } catch (SQLException ex) { - logger.warn("Error while retrieving metadata for table columns: " + ex.getMessage()); + if (logger.isWarnEnabled()) { + logger.warn("Error while retrieving metadata for table columns: " + ex.getMessage()); + } } finally { - try { - if (tableColumns != null) - tableColumns.close(); - } - catch (SQLException ex) { - logger.warn("Problem closing ResultSet for table column metadata " + ex.getMessage()); - } + JdbcUtils.closeResultSet(tableColumns); } - }