added support to SimpleJdbcInsert for including synonyms when table metadata is retrieved; this only applies to Oracle (SPR-4782)
This commit is contained in:
parent
1d6a3e5360
commit
f70d14e2c2
|
|
@ -361,7 +361,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
|||
}
|
||||
}
|
||||
catch (SQLException se) {
|
||||
logger.warn("Error while retreiving metadata for procedure columns: " + se.getMessage());
|
||||
logger.warn("Error while retreiving metadata for table columns: " + se.getMessage());
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
|
|
@ -369,7 +369,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
|||
tableColumns.close();
|
||||
}
|
||||
catch (SQLException se) {
|
||||
logger.warn("Problem closing resultset for procedure column metadata " + se.getMessage());
|
||||
logger.warn("Problem closing resultset for table column metadata " + se.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright 2002-2007 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jdbc.core.metadata;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Connection;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
|
||||
/**
|
||||
* The 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
|
||||
* @since 3.0
|
||||
*/
|
||||
public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
|
||||
|
||||
private boolean includeSynonyms;
|
||||
|
||||
|
||||
public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
this(databaseMetaData, false);
|
||||
}
|
||||
|
||||
public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData, boolean includeSynonyms) throws SQLException {
|
||||
super(databaseMetaData);
|
||||
this.includeSynonyms = includeSynonyms;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
|
||||
String catalogName, String schemaName, String tableName) throws SQLException {
|
||||
|
||||
Connection con = databaseMetaData.getConnection();
|
||||
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 (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);
|
||||
}
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,8 +30,6 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.jdbc.core.SqlTypeValue;
|
||||
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
|
||||
import org.springframework.jdbc.support.JdbcUtils;
|
||||
|
|
@ -61,15 +59,17 @@ public class TableMetaDataContext {
|
|||
private List<String> tableColumns = new ArrayList<String>();
|
||||
|
||||
/** should we access insert parameter meta data info or not */
|
||||
private boolean accessTableParameterMetaData = true;
|
||||
private boolean accessTableColumnMetaData = true;
|
||||
|
||||
/** the provider of call meta data */
|
||||
/** should we override default for including synonyms for meta data lookups */
|
||||
private boolean overrideIncludeSynonymsDefault = false;
|
||||
|
||||
/** the provider of table meta data */
|
||||
private TableMetaDataProvider metaDataProvider;
|
||||
|
||||
/** are we using generated key columns */
|
||||
private boolean generatedKeyColumnsUsed = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the table for this context.
|
||||
*/
|
||||
|
|
@ -115,18 +115,32 @@ public class TableMetaDataContext {
|
|||
/**
|
||||
* Specify whether we should access table column meta data.
|
||||
*/
|
||||
public void setAccessTableParameterMetaData(boolean accessTableParameterMetaData) {
|
||||
this.accessTableParameterMetaData = accessTableParameterMetaData;
|
||||
public void setAccessTableColumnMetaData(boolean accessTableColumnMetaData) {
|
||||
this.accessTableColumnMetaData = accessTableColumnMetaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we accessing table meta data?
|
||||
*/
|
||||
public boolean isAccessTableParameterMetaData() {
|
||||
return this.accessTableParameterMetaData;
|
||||
public boolean isAccessTableColumnMetaData() {
|
||||
return this.accessTableColumnMetaData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify whether we should override default for accessing synonyms.
|
||||
*/
|
||||
public void setOverrideIncludeSynonymsDefault(boolean override) {
|
||||
this.overrideIncludeSynonymsDefault = override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we overrding include synonyms default?
|
||||
*/
|
||||
public boolean isOverrideIncludeSynonymsDefault() {
|
||||
return this.overrideIncludeSynonymsDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of the table column names.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -54,10 +54,15 @@ public class TableMetaDataProviderFactory {
|
|||
|
||||
public Object processMetaData(DatabaseMetaData databaseMetaData)
|
||||
throws SQLException, MetaDataAccessException {
|
||||
String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
|
||||
boolean accessTableColumnMetaData = context.isAccessTableParameterMetaData();
|
||||
String databaseProductName =
|
||||
JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
|
||||
boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData();
|
||||
TableMetaDataProvider provider;
|
||||
if ("HSQL Database Engine".equals(databaseProductName)) {
|
||||
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)) {
|
||||
|
|
@ -74,7 +79,8 @@ public class TableMetaDataProviderFactory {
|
|||
}
|
||||
provider.initializeWithMetaData(databaseMetaData);
|
||||
if (accessTableColumnMetaData) {
|
||||
provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getTableName());
|
||||
provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(),
|
||||
context.getSchemaName(), context.getTableName());
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,20 @@ public abstract class AbstractJdbcInsert {
|
|||
this.generatedKeyNames = new String[] {generatedKeyName};
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the parameter metadata for the call should be used. The default is true.
|
||||
*/
|
||||
public void setAccessTableColumnMetaData(boolean accessTableColumnMetaData) {
|
||||
this.tableMetaDataContext.setAccessTableColumnMetaData(accessTableColumnMetaData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the default for including synonyms should be changed. The default is false.
|
||||
*/
|
||||
public void setOverrideIncludeSynonymsDefault(boolean override) {
|
||||
this.tableMetaDataContext.setOverrideIncludeSynonymsDefault(override);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the insert string to be used
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -94,6 +94,16 @@ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcIn
|
|||
return this;
|
||||
}
|
||||
|
||||
public SimpleJdbcInsertOperations withoutTableColumnMetaDataAccess() {
|
||||
setAccessTableColumnMetaData(false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData() {
|
||||
setOverrideIncludeSynonymsDefault(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int execute(Map<String, Object> args) {
|
||||
return doExecute(args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,21 @@ public interface SimpleJdbcInsertOperations {
|
|||
*/
|
||||
SimpleJdbcInsertOperations usingGeneratedKeyColumns(String... columnNames);
|
||||
|
||||
/**
|
||||
* Turn off any processing of column meta data information obtained via JDBC.
|
||||
* @return the instance of this SimpleJdbcInsert
|
||||
*/
|
||||
SimpleJdbcInsertOperations withoutTableColumnMetaDataAccess();
|
||||
|
||||
/**
|
||||
* Include synonyms for the column meta data lookups via JDBC.
|
||||
* Note: this is only necessary to include for Oracle since other
|
||||
* databases supporting synonyms seems to include the synonyms
|
||||
* automatically.
|
||||
* @return the instance of this SimpleJdbcInsert
|
||||
*/
|
||||
SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData();
|
||||
|
||||
|
||||
/**
|
||||
* Execute the insert using the values passed in.
|
||||
|
|
|
|||
Loading…
Reference in New Issue