GenericTableMetaDataProvider falls back to single schema as default
Issue: SPR-15090
This commit is contained in:
		
							parent
							
								
									50e5a65b2d
								
							
						
					
					
						commit
						de4349792b
					
				| 
						 | 
				
			
			@ -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<String, TableMetaData> 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<String, TableMetaData> 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue