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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
import org.springframework.jdbc.support.JdbcUtils;
|
||||||
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +38,7 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||||
* enough features for all supported databases.
|
* enough features for all supported databases.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
|
@ -163,17 +165,23 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys' - " + ex.getMessage());
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys': " + ex.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String databaseProductName = databaseMetaData.getDatabaseProductName();
|
String databaseProductName = databaseMetaData.getDatabaseProductName();
|
||||||
if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) {
|
if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName);
|
logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName);
|
||||||
|
}
|
||||||
setGeneratedKeysColumnNameArraySupported(false);
|
setGeneratedKeysColumnNameArraySupported(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (isGetGeneratedKeysSupported()) {
|
if (isGetGeneratedKeysSupported()) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName);
|
logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName);
|
||||||
|
}
|
||||||
setGeneratedKeysColumnNameArraySupported(true);
|
setGeneratedKeysColumnNameArraySupported(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -182,25 +190,36 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + ex.getMessage());
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName': " + ex.getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.databaseVersion = databaseMetaData.getDatabaseProductVersion();
|
this.databaseVersion = databaseMetaData.getDatabaseProductVersion();
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + ex.getMessage());
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion': " + ex.getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers());
|
setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers());
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + ex.getMessage());
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers': " + ex.getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers());
|
setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers());
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
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.
|
* Provide access to default schema for subclasses.
|
||||||
*/
|
*/
|
||||||
protected String getDefaultSchema() {
|
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.
|
* Method supporting the metedata processing for a table.
|
||||||
*/
|
*/
|
||||||
private void locateTableAndProcessMetaData(DatabaseMetaData databaseMetaData, String catalogName,
|
private void locateTableAndProcessMetaData(
|
||||||
String schemaName, String tableName) {
|
DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) {
|
||||||
|
|
||||||
Map<String, TableMetaData> tableMeta = new HashMap<>();
|
Map<String, TableMetaData> tableMeta = new HashMap<>();
|
||||||
ResultSet tables = null;
|
ResultSet tables = null;
|
||||||
try {
|
try {
|
||||||
tables = databaseMetaData.getTables(
|
tables = databaseMetaData.getTables(
|
||||||
catalogNameToUse(catalogName),
|
catalogNameToUse(catalogName), schemaNameToUse(schemaName), tableNameToUse(tableName), null);
|
||||||
schemaNameToUse(schemaName),
|
|
||||||
tableNameToUse(tableName),
|
|
||||||
null);
|
|
||||||
while (tables != null && tables.next()) {
|
while (tables != null && tables.next()) {
|
||||||
TableMetaData tmd = new TableMetaData();
|
TableMetaData tmd = new TableMetaData();
|
||||||
tmd.setCatalogName(tables.getString("TABLE_CAT"));
|
tmd.setCatalogName(tables.getString("TABLE_CAT"));
|
||||||
|
@ -316,28 +332,40 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
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 {
|
finally {
|
||||||
if (tables != null) {
|
JdbcUtils.closeResultSet(tables);
|
||||||
try {
|
|
||||||
tables.close();
|
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
|
||||||
logger.warn("Error while closing table meta data results" + ex.getMessage());
|
if (tableMeta.isEmpty()) {
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
|
logger.warn("Unable to locate table meta data for '" + tableName + "': column names must be provided");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
processTableColumns(databaseMetaData, findTableMetaData(schemaName, tableName, tableMeta));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableMeta.size() < 1) {
|
private TableMetaData findTableMetaData(String schemaName, String tableName, Map<String, TableMetaData> tableMeta) {
|
||||||
logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided");
|
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 {
|
else {
|
||||||
TableMetaData tmd;
|
TableMetaData tmd = tableMeta.get(getDefaultSchema());
|
||||||
if (schemaName == null) {
|
|
||||||
tmd = tableMeta.get(getDefaultSchema());
|
|
||||||
if (tmd == null) {
|
if (tmd == null) {
|
||||||
tmd = tableMeta.get(userName != null ? userName.toUpperCase() : "");
|
tmd = tableMeta.get(this.userName != null ? this.userName.toUpperCase() : "");
|
||||||
}
|
}
|
||||||
if (tmd == null) {
|
if (tmd == null) {
|
||||||
tmd = tableMeta.get("PUBLIC");
|
tmd = tableMeta.get("PUBLIC");
|
||||||
|
@ -346,19 +374,10 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
tmd = tableMeta.get("DBO");
|
tmd = tableMeta.get("DBO");
|
||||||
}
|
}
|
||||||
if (tmd == null) {
|
if (tmd == null) {
|
||||||
throw new DataAccessResourceFailureException("Unable to locate table meta data for '" +
|
throw new DataAccessResourceFailureException(
|
||||||
tableName + "' in the default schema");
|
"Unable to locate table meta data for '" + tableName + "' in the default schema");
|
||||||
}
|
}
|
||||||
}
|
return tmd;
|
||||||
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, tmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,10 +408,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
if ("NUMBER".equals(typeName) && decimalDigits == 0) {
|
if ("NUMBER".equals(typeName) && decimalDigits == 0) {
|
||||||
dataType = Types.NUMERIC;
|
dataType = Types.NUMERIC;
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Overriding metadata: "
|
logger.debug("Overriding metadata: " + columnName + " now NUMERIC instead of DECIMAL");
|
||||||
+ columnName +
|
|
||||||
" now using NUMERIC instead of DECIMAL"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,24 +416,19 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
TableParameterMetaData meta = new TableParameterMetaData(columnName, dataType, nullable);
|
TableParameterMetaData meta = new TableParameterMetaData(columnName, dataType, nullable);
|
||||||
this.tableParameterMetaData.add(meta);
|
this.tableParameterMetaData.add(meta);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Retrieved metadata: " + meta.getParameterName() +
|
logger.debug("Retrieved metadata: " + meta.getParameterName() + " " +
|
||||||
" " + meta.getSqlType() + " " + meta.isNullable());
|
meta.getSqlType() + " " + meta.isNullable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
|
if (logger.isWarnEnabled()) {
|
||||||
logger.warn("Error while retrieving metadata for table columns: " + ex.getMessage());
|
logger.warn("Error while retrieving metadata for table columns: " + ex.getMessage());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
try {
|
JdbcUtils.closeResultSet(tableColumns);
|
||||||
if (tableColumns != null)
|
|
||||||
tableColumns.close();
|
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
|
||||||
logger.warn("Problem closing ResultSet for table column metadata " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue