revised OracleTableMetaDataProvider for reliable Oracle Connection detection; autodetect JdbcTemplate's NativeJdbcExtractor (SPR-7611)
This commit is contained in:
parent
1f1577e33e
commit
0f924820e8
|
@ -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");
|
* 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.
|
||||||
|
@ -33,8 +33,8 @@ import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic implementation of the {@link TableMetaDataProvider} that should provide enough features for all supported
|
* A generic implementation of the {@link TableMetaDataProvider} that should provide
|
||||||
* databases.
|
* enough features for all supported databases.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @since 2.5
|
* @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 */
|
/** database products we know not supporting the use of a String[] for generated keys */
|
||||||
private List productsNotSupportingGeneratedKeysColumnNameArray =
|
private List productsNotSupportingGeneratedKeysColumnNameArray =
|
||||||
Arrays.asList(new String[] {"Apache Derby", "HSQL Database Engine"});
|
Arrays.asList("Apache Derby", "HSQL Database Engine");
|
||||||
|
|
||||||
/** Collection of TableParameterMetaData objects */
|
/** Collection of TableParameterMetaData objects */
|
||||||
private List<TableParameterMetaData> insertParameterMetaData = new ArrayList<TableParameterMetaData>();
|
private List<TableParameterMetaData> insertParameterMetaData = new ArrayList<TableParameterMetaData>();
|
||||||
|
|
||||||
/** NativeJdbcExtractor that can be used to retrieve the native connection */
|
/** 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.
|
* Constructor used to initialize with provided database meta data.
|
||||||
* @param databaseMetaData meta data to be used
|
* @param databaseMetaData meta data to be used
|
||||||
* @throws SQLException
|
|
||||||
*/
|
*/
|
||||||
protected GenericTableMetaDataProvider(DatabaseMetaData databaseMetaData) 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
|
* 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() {
|
public boolean isStoresUpperCaseIdentifiers() {
|
||||||
return storesLowerCaseIdentifiers;
|
return this.storesUpperCaseIdentifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether identifiers use lower case
|
* Specify whether identifiers use lower case.
|
||||||
*/
|
*/
|
||||||
public void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) {
|
public void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) {
|
||||||
this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers;
|
this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether identifiers use lower case
|
||||||
|
*/
|
||||||
|
public boolean isStoresLowerCaseIdentifiers() {
|
||||||
|
return this.storesLowerCaseIdentifiers;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTableColumnMetaDataUsed() {
|
public boolean isTableColumnMetaDataUsed() {
|
||||||
return tableColumnMetaDataUsed;
|
return this.tableColumnMetaDataUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TableParameterMetaData> getTableParameterMetaData() {
|
public List<TableParameterMetaData> getTableParameterMetaData() {
|
||||||
return insertParameterMetaData;
|
return this.insertParameterMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGetGeneratedKeysSupported() {
|
public boolean isGetGeneratedKeysSupported() {
|
||||||
return getGeneratedKeysSupported;
|
return this.getGeneratedKeysSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGetGeneratedKeysSimulated(){
|
public boolean isGetGeneratedKeysSimulated(){
|
||||||
|
@ -140,10 +140,6 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
this.getGeneratedKeysSupported = getGeneratedKeysSupported;
|
this.getGeneratedKeysSupported = getGeneratedKeysSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGeneratedKeysColumnNameArraySupported() {
|
|
||||||
return generatedKeysColumnNameArraySupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether a column name array is supported for generated keys
|
* Specify whether a column name array is supported for generated keys
|
||||||
*/
|
*/
|
||||||
|
@ -151,12 +147,20 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported;
|
this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGeneratedKeysColumnNameArraySupported() {
|
||||||
|
return this.generatedKeysColumnNameArraySupported;
|
||||||
|
}
|
||||||
|
|
||||||
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
||||||
this.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 {
|
try {
|
||||||
if (databaseMetaData.supportsGetGeneratedKeys()) {
|
if (databaseMetaData.supportsGetGeneratedKeys()) {
|
||||||
logger.debug("GetGeneratedKeys is supported");
|
logger.debug("GetGeneratedKeys is supported");
|
||||||
|
@ -172,7 +176,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String databaseProductName = databaseMetaData.getDatabaseProductName();
|
String databaseProductName = databaseMetaData.getDatabaseProductName();
|
||||||
if (productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) {
|
if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) {
|
||||||
logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName);
|
logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName);
|
||||||
setGeneratedKeysColumnNameArraySupported(false);
|
setGeneratedKeysColumnNameArraySupported(false);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +189,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + se.getMessage());
|
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + se.getMessage());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
databaseVersion = databaseMetaData.getDatabaseProductVersion();
|
this.databaseVersion = databaseMetaData.getDatabaseProductVersion();
|
||||||
}
|
}
|
||||||
catch (SQLException se) {
|
catch (SQLException se) {
|
||||||
logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + se.getMessage());
|
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)
|
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName,
|
||||||
throws SQLException {
|
String schemaName, String tableName) throws SQLException {
|
||||||
|
|
||||||
tableColumnMetaDataUsed = true;
|
|
||||||
|
|
||||||
|
this.tableColumnMetaDataUsed = true;
|
||||||
locateTableAndProcessMetaData(databaseMetaData, catalogName, schemaName, tableName);
|
locateTableAndProcessMetaData(databaseMetaData, catalogName, schemaName, tableName);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String tableNameToUse(String tableName) {
|
public String tableNameToUse(String tableName) {
|
||||||
if (tableName == null)
|
if (tableName == null) {
|
||||||
return null;
|
return null;
|
||||||
else if (isStoresUpperCaseIdentifiers())
|
}
|
||||||
|
else if (isStoresUpperCaseIdentifiers()) {
|
||||||
return tableName.toUpperCase();
|
return tableName.toUpperCase();
|
||||||
else if(isStoresLowerCaseIdentifiers())
|
}
|
||||||
|
else if(isStoresLowerCaseIdentifiers()) {
|
||||||
return tableName.toLowerCase();
|
return tableName.toLowerCase();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
return tableName;
|
return tableName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String catalogNameToUse(String catalogName) {
|
public String catalogNameToUse(String catalogName) {
|
||||||
if (catalogName == null)
|
if (catalogName == null) {
|
||||||
return null;
|
return null;
|
||||||
else if (isStoresUpperCaseIdentifiers())
|
}
|
||||||
|
else if (isStoresUpperCaseIdentifiers()) {
|
||||||
return catalogName.toUpperCase();
|
return catalogName.toUpperCase();
|
||||||
else if(isStoresLowerCaseIdentifiers())
|
}
|
||||||
|
else if(isStoresLowerCaseIdentifiers()) {
|
||||||
return catalogName.toLowerCase();
|
return catalogName.toLowerCase();
|
||||||
else
|
}
|
||||||
return catalogName;
|
else {
|
||||||
|
return catalogName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String schemaNameToUse(String schemaName) {
|
public String schemaNameToUse(String schemaName) {
|
||||||
if (schemaName == null)
|
if (schemaName == null) {
|
||||||
return null;
|
return null;
|
||||||
else if (isStoresUpperCaseIdentifiers())
|
}
|
||||||
|
else if (isStoresUpperCaseIdentifiers()) {
|
||||||
return schemaName.toUpperCase();
|
return schemaName.toUpperCase();
|
||||||
else if(isStoresLowerCaseIdentifiers())
|
}
|
||||||
|
else if(isStoresLowerCaseIdentifiers()) {
|
||||||
return schemaName.toLowerCase();
|
return schemaName.toLowerCase();
|
||||||
else
|
}
|
||||||
return schemaName;
|
else {
|
||||||
|
return schemaName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String metaDataCatalogNameToUse(String catalogName) {
|
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() {
|
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<String, TableMetaData> tableMeta = new HashMap<String, TableMetaData>();
|
Map<String, TableMetaData> tableMeta = new HashMap<String, TableMetaData>();
|
||||||
ResultSet tables = null;
|
ResultSet tables = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tables = databaseMetaData.getTables(
|
tables = databaseMetaData.getTables(
|
||||||
catalogNameToUse(catalogName),
|
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");
|
logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TableMetaData tmd = null;
|
TableMetaData tmd;
|
||||||
if (schemaName == null) {
|
if (schemaName == null) {
|
||||||
tmd = tableMeta.get(userName.toUpperCase());
|
tmd = tableMeta.get(userName.toUpperCase());
|
||||||
if (tmd == null) {
|
if (tmd == null) {
|
||||||
|
@ -320,14 +334,16 @@ 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 '" + tableName + "' in the default schema");
|
throw new DataAccessResourceFailureException("Unable to locate table meta data for '" +
|
||||||
|
tableName + "' in the default schema");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmd = tableMeta.get(schemaName.toUpperCase());
|
tmd = tableMeta.get(schemaName.toUpperCase());
|
||||||
if (tmd == null) {
|
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,
|
dataType,
|
||||||
nullable
|
nullable
|
||||||
);
|
);
|
||||||
insertParameterMetaData.add(meta);
|
this.insertParameterMetaData.add(meta);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Retrieved metadata: "
|
logger.debug("Retrieved metadata: "
|
||||||
+ meta.getParameterName() +
|
+ meta.getParameterName() +
|
||||||
|
@ -389,7 +405,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException se) {
|
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 {
|
finally {
|
||||||
try {
|
try {
|
||||||
|
@ -397,7 +413,7 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
|
||||||
tableColumns.close();
|
tableColumns.close();
|
||||||
}
|
}
|
||||||
catch (SQLException se) {
|
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 catalogName;
|
||||||
|
|
||||||
private String schemaName;
|
private String schemaName;
|
||||||
|
|
||||||
private String tableName;
|
private String tableName;
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
|
||||||
public String getCatalogName() {
|
|
||||||
return catalogName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCatalogName(String catalogName) {
|
public void setCatalogName(String catalogName) {
|
||||||
this.catalogName = catalogName;
|
this.catalogName = catalogName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSchemaName() {
|
public String getCatalogName() {
|
||||||
return schemaName;
|
return this.catalogName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSchemaName(String schemaName) {
|
public void setSchemaName(String schemaName) {
|
||||||
this.schemaName = schemaName;
|
this.schemaName = schemaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTableName() {
|
public String getSchemaName() {
|
||||||
return tableName;
|
return this.schemaName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTableName(String tableName) {
|
public void setTableName(String tableName) {
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getTableName() {
|
||||||
return type;
|
return this.tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type) {
|
public void setType(String type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -22,17 +22,20 @@ import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
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.
|
* Supports a feature for including synonyms in the metadata lookup.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
|
public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
|
||||||
|
|
||||||
private boolean includeSynonyms;
|
private final boolean includeSynonyms;
|
||||||
|
|
||||||
|
|
||||||
public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
|
public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||||
|
@ -49,67 +52,61 @@ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider {
|
||||||
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
|
public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData,
|
||||||
String catalogName, String schemaName, String tableName) throws SQLException {
|
String catalogName, String schemaName, String tableName) throws SQLException {
|
||||||
|
|
||||||
Connection con = null;
|
if (!this.includeSynonyms) {
|
||||||
if (nativeJdbcExtractor == null) {
|
logger.debug("Defaulting to no synonyms in table metadata lookup");
|
||||||
con = databaseMetaData.getConnection();
|
super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName);
|
||||||
if (logger.isDebugEnabled()) {
|
return;
|
||||||
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 (includeSynonyms && con.getClass().getName().startsWith("oracle")) {
|
Connection con = databaseMetaData.getConnection();
|
||||||
try {
|
NativeJdbcExtractor nativeJdbcExtractor = getNativeJdbcExtractor();
|
||||||
methodToInvoke = con.getClass().getMethod("getIncludeSynonyms", (Class[]) null);
|
if (nativeJdbcExtractor != null) {
|
||||||
methodToInvoke.setAccessible(true);
|
con = nativeJdbcExtractor.getNativeConnection(con);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
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);
|
super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName);
|
||||||
if (includeSynonyms && con.getClass().getName().startsWith("oracle")) {
|
|
||||||
try {
|
try {
|
||||||
methodToInvoke = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class});
|
setIncludeSynonyms.invoke(con, originalValueForIncludeSynonyms);
|
||||||
methodToInvoke.setAccessible(true);
|
}
|
||||||
methodToInvoke.invoke(con, origValueForIncludeSynonyms);
|
catch (Exception ex) {
|
||||||
}
|
throw new InvalidDataAccessApiUsageException("Couldn't reset Oracle Connection", ex);
|
||||||
catch (Exception ex) {
|
|
||||||
throw new InvalidDataAccessApiUsageException(
|
|
||||||
"Couldn't restore Oracle Connection.", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
|
@ -72,7 +72,8 @@ public class TableMetaDataContext {
|
||||||
private boolean generatedKeyColumnsUsed = false;
|
private boolean generatedKeyColumnsUsed = false;
|
||||||
|
|
||||||
/** NativeJdbcExtractor to be used to retrieve the native connection */
|
/** NativeJdbcExtractor to be used to retrieve the native connection */
|
||||||
NativeJdbcExtractor nativeJdbcExtractor = null;
|
NativeJdbcExtractor nativeJdbcExtractor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of the table for this context.
|
* 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
|
* 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()}?
|
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||||
*/
|
*/
|
||||||
public boolean isGetGeneratedKeysSimulated() {
|
public boolean isGetGeneratedKeysSimulated() {
|
||||||
|
@ -171,7 +172,7 @@ public class TableMetaDataContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this database support simple query to retrieve generated keys
|
* 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()}?
|
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||||
*/
|
*/
|
||||||
public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
|
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[])}?
|
* {@link java.sql.Connection#createStruct(String, Object[])}?
|
||||||
*/
|
*/
|
||||||
public boolean isGeneratedKeysColumnNameArraySupported() {
|
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) {
|
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
||||||
this.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 dataSource the DataSource being used
|
||||||
* @param declaredColumns any columns that are declared
|
* @param declaredColumns any columns that are declared
|
||||||
* @param generatedKeyNames name of generated keys
|
* @param generatedKeyNames name of generated keys
|
||||||
|
@ -212,7 +213,7 @@ public class TableMetaDataContext {
|
||||||
*/
|
*/
|
||||||
protected List<String> reconcileColumnsToUse(List<String> declaredColumns, String[] generatedKeyNames) {
|
protected List<String> reconcileColumnsToUse(List<String> declaredColumns, String[] generatedKeyNames) {
|
||||||
if (generatedKeyNames.length > 0) {
|
if (generatedKeyNames.length > 0) {
|
||||||
generatedKeyColumnsUsed = true;
|
this.generatedKeyColumnsUsed = true;
|
||||||
}
|
}
|
||||||
if (declaredColumns.size() > 0) {
|
if (declaredColumns.size() > 0) {
|
||||||
return new ArrayList<String>(declaredColumns);
|
return new ArrayList<String>(declaredColumns);
|
||||||
|
@ -240,7 +241,7 @@ public class TableMetaDataContext {
|
||||||
// database metadata is not necessarily providing case sensitive column names
|
// database metadata is not necessarily providing case sensitive column names
|
||||||
Map caseInsensitiveParameterNames =
|
Map caseInsensitiveParameterNames =
|
||||||
SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource);
|
SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource);
|
||||||
for (String column : tableColumns) {
|
for (String column : this.tableColumns) {
|
||||||
if (parameterSource.hasValue(column)) {
|
if (parameterSource.hasValue(column)) {
|
||||||
values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column));
|
values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column));
|
||||||
}
|
}
|
||||||
|
@ -280,7 +281,7 @@ public class TableMetaDataContext {
|
||||||
for (String key : inParameters.keySet()) {
|
for (String key : inParameters.keySet()) {
|
||||||
source.put(key.toLowerCase(), inParameters.get(key));
|
source.put(key.toLowerCase(), inParameters.get(key));
|
||||||
}
|
}
|
||||||
for (String column : tableColumns) {
|
for (String column : this.tableColumns) {
|
||||||
values.add(source.get(column.toLowerCase()));
|
values.add(source.get(column.toLowerCase()));
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
|
@ -316,7 +317,7 @@ public class TableMetaDataContext {
|
||||||
}
|
}
|
||||||
insertStatement.append(") VALUES(");
|
insertStatement.append(") VALUES(");
|
||||||
if (columnCount < 1) {
|
if (columnCount < 1) {
|
||||||
if (generatedKeyColumnsUsed) {
|
if (this.generatedKeyColumnsUsed) {
|
||||||
logger.info("Unable to locate non-key columns for table '" +
|
logger.info("Unable to locate non-key columns for table '" +
|
||||||
this.getTableName() + "' so an empty insert statement is generated");
|
this.getTableName() + "' so an empty insert statement is generated");
|
||||||
}
|
}
|
||||||
|
@ -340,15 +341,12 @@ public class TableMetaDataContext {
|
||||||
* @return the array of types to be used
|
* @return the array of types to be used
|
||||||
*/
|
*/
|
||||||
public int[] createInsertTypes() {
|
public int[] createInsertTypes() {
|
||||||
|
|
||||||
int[] types = new int[this.getTableColumns().size()];
|
int[] types = new int[this.getTableColumns().size()];
|
||||||
|
|
||||||
List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
|
List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
|
||||||
Map<String, TableParameterMetaData> parameterMap = new HashMap<String, TableParameterMetaData>(parameters.size());
|
Map<String, TableParameterMetaData> parameterMap = new HashMap<String, TableParameterMetaData>(parameters.size());
|
||||||
for (TableParameterMetaData tpmd : parameters) {
|
for (TableParameterMetaData tpmd : parameters) {
|
||||||
parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd);
|
parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int typeIndx = 0;
|
int typeIndx = 0;
|
||||||
for (String column : this.getTableColumns()) {
|
for (String column : this.getTableColumns()) {
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
|
@ -365,7 +363,6 @@ public class TableMetaDataContext {
|
||||||
}
|
}
|
||||||
typeIndx++;
|
typeIndx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -18,7 +18,6 @@ package org.springframework.jdbc.core.metadata;
|
||||||
|
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -38,74 +37,70 @@ import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||||
*/
|
*/
|
||||||
public class TableMetaDataProviderFactory {
|
public class TableMetaDataProviderFactory {
|
||||||
|
|
||||||
/** Logger */
|
|
||||||
private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class);
|
private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TableMetaDataProvider based on the database metedata
|
* Create a TableMetaDataProvider based on the database metedata
|
||||||
* @param dataSource used to retrieve metedata
|
* @param dataSource used to retrieve metedata
|
||||||
* @param context the class that holds configuration and metedata
|
* @param context the class that holds configuration and metedata
|
||||||
* @return instance of the TableMetaDataProvider implementation to be used
|
* @return instance of the TableMetaDataProvider implementation to be used
|
||||||
*/
|
*/
|
||||||
static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource,
|
public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, TableMetaDataContext context) {
|
||||||
final TableMetaDataContext context) {
|
|
||||||
return createMetaDataProvider(dataSource, context, null);
|
return createMetaDataProvider(dataSource, context, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TableMetaDataProvider based on the database metedata
|
* Create a TableMetaDataProvider based on the database metedata
|
||||||
* @param dataSource used to retrieve metedata
|
* @param dataSource used to retrieve metedata
|
||||||
* @param context the class that holds configuration and 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
|
* @return instance of the TableMetaDataProvider implementation to be used
|
||||||
*/
|
*/
|
||||||
static public TableMetaDataProvider createMetaDataProvider(DataSource dataSource,
|
public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource,
|
||||||
final TableMetaDataContext context,
|
final TableMetaDataContext context, final NativeJdbcExtractor nativeJdbcExtractor) {
|
||||||
final NativeJdbcExtractor nativeJdbcExtractor) {
|
|
||||||
try {
|
try {
|
||||||
return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(
|
return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource,
|
||||||
dataSource, new DatabaseMetaDataCallback() {
|
new DatabaseMetaDataCallback() {
|
||||||
|
public Object processMetaData(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||||
public Object processMetaData(DatabaseMetaData databaseMetaData)
|
String databaseProductName =
|
||||||
throws SQLException, MetaDataAccessException {
|
JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
|
||||||
String databaseProductName =
|
boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData();
|
||||||
JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName());
|
TableMetaDataProvider provider;
|
||||||
boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData();
|
if ("Oracle".equals(databaseProductName)) {
|
||||||
TableMetaDataProvider provider;
|
provider = new OracleTableMetaDataProvider(databaseMetaData,
|
||||||
if ("Oracle".equals(databaseProductName)) {
|
context.isOverrideIncludeSynonymsDefault());
|
||||||
provider = new OracleTableMetaDataProvider(databaseMetaData,
|
}
|
||||||
context.isOverrideIncludeSynonymsDefault());
|
else if ("HSQL Database Engine".equals(databaseProductName)) {
|
||||||
}
|
provider = new HsqlTableMetaDataProvider(databaseMetaData);
|
||||||
else if ("HSQL Database Engine".equals(databaseProductName)) {
|
}
|
||||||
provider = new HsqlTableMetaDataProvider(databaseMetaData);
|
else if ("PostgreSQL".equals(databaseProductName)) {
|
||||||
}
|
provider = new PostgresTableMetaDataProvider(databaseMetaData);
|
||||||
else if ("PostgreSQL".equals(databaseProductName)) {
|
}
|
||||||
provider = new PostgresTableMetaDataProvider(databaseMetaData);
|
else if ("Apache Derby".equals(databaseProductName)) {
|
||||||
}
|
provider = new DerbyTableMetaDataProvider(databaseMetaData);
|
||||||
else if ("Apache Derby".equals(databaseProductName)) {
|
}
|
||||||
provider = new DerbyTableMetaDataProvider(databaseMetaData);
|
else {
|
||||||
}
|
provider = new GenericTableMetaDataProvider(databaseMetaData);
|
||||||
else {
|
}
|
||||||
provider = new GenericTableMetaDataProvider(databaseMetaData);
|
if (nativeJdbcExtractor != null) {
|
||||||
}
|
provider.setNativeJdbcExtractor(nativeJdbcExtractor);
|
||||||
if (nativeJdbcExtractor != null) {
|
}
|
||||||
provider.setNativeJdbcExtractor(nativeJdbcExtractor);
|
if (logger.isDebugEnabled()) {
|
||||||
}
|
logger.debug("Using " + provider.getClass().getSimpleName());
|
||||||
if (logger.isDebugEnabled()) {
|
}
|
||||||
logger.debug("Using " + provider.getClass().getName());
|
provider.initializeWithMetaData(databaseMetaData);
|
||||||
}
|
if (accessTableColumnMetaData) {
|
||||||
provider.initializeWithMetaData(databaseMetaData);
|
provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(),
|
||||||
if (accessTableColumnMetaData) {
|
context.getSchemaName(), context.getTableName());
|
||||||
provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(),
|
}
|
||||||
context.getSchemaName(), context.getTableName());
|
return provider;
|
||||||
}
|
}
|
||||||
return provider;
|
});
|
||||||
}
|
}
|
||||||
});
|
catch (MetaDataAccessException ex) {
|
||||||
} catch (MetaDataAccessException e) {
|
throw new DataAccessResourceFailureException("Error retrieving database metadata", ex);
|
||||||
throw new DataAccessResourceFailureException("Error retreiving database metadata", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* 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.
|
||||||
|
@ -18,25 +18,24 @@ package org.springframework.jdbc.core.simple;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
|
||||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||||
import org.springframework.jdbc.core.ConnectionCallback;
|
import org.springframework.jdbc.core.ConnectionCallback;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
@ -57,6 +56,7 @@ import org.springframework.util.Assert;
|
||||||
* This class provides the base SPI for {@link SimpleJdbcInsert}.
|
* This class provides the base SPI for {@link SimpleJdbcInsert}.
|
||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractJdbcInsert {
|
public abstract class AbstractJdbcInsert {
|
||||||
|
@ -65,10 +65,13 @@ public abstract class AbstractJdbcInsert {
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
/** Lower-level class used to execute SQL */
|
/** 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 */
|
/** List of columns objects to be used in insert statement */
|
||||||
private List<String> declaredColumns = new ArrayList<String>();
|
private final List<String> declaredColumns = new ArrayList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has this operation been compiled? Compilation means at
|
* Has this operation been compiled? Compilation means at
|
||||||
|
@ -77,31 +80,30 @@ public abstract class AbstractJdbcInsert {
|
||||||
*/
|
*/
|
||||||
private boolean compiled = false;
|
private boolean compiled = false;
|
||||||
|
|
||||||
/** the generated string used for insert statement */
|
/** The generated string used for insert statement */
|
||||||
private String insertString;
|
private String insertString;
|
||||||
|
|
||||||
/** the SQL Type information for the insert columns */
|
/** The SQL type information for the insert columns */
|
||||||
private int[] insertTypes;
|
private int[] insertTypes;
|
||||||
|
|
||||||
/** the names of the columns holding the generated key */
|
/** The names of the columns holding the generated key */
|
||||||
private String[] generatedKeyNames = new String[] {};
|
private String[] generatedKeyNames = new String[0];
|
||||||
|
|
||||||
/** context used to retrieve and manage database metadata */
|
|
||||||
private TableMetaDataContext tableMetaDataContext = new TableMetaDataContext();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for sublasses to delegate to for setting the DataSource.
|
* Constructor for sublasses to delegate to for setting the DataSource.
|
||||||
*/
|
*/
|
||||||
protected AbstractJdbcInsert(DataSource dataSource) {
|
protected AbstractJdbcInsert(DataSource dataSource) {
|
||||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for sublasses to delegate to for setting the JdbcTemplate.
|
* Constructor for sublasses to delegate to for setting the JdbcTemplate.
|
||||||
*/
|
*/
|
||||||
protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) {
|
protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) {
|
||||||
|
Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null");
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
setNativeJdbcExtractor(jdbcTemplate.getNativeJdbcExtractor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,26 +111,19 @@ public abstract class AbstractJdbcInsert {
|
||||||
// Methods dealing with configuaration properties
|
// 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
|
* Set the name of the table for this insert
|
||||||
*/
|
*/
|
||||||
public void setTableName(String tableName) {
|
public void setTableName(String tableName) {
|
||||||
checkIfConfigurationModificationIsAllowed();
|
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() {
|
public String getTableName() {
|
||||||
return tableMetaDataContext.getSchemaName();
|
return this.tableMetaDataContext.getTableName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,14 +131,14 @@ public abstract class AbstractJdbcInsert {
|
||||||
*/
|
*/
|
||||||
public void setSchemaName(String schemaName) {
|
public void setSchemaName(String schemaName) {
|
||||||
checkIfConfigurationModificationIsAllowed();
|
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() {
|
public String getSchemaName() {
|
||||||
return tableMetaDataContext.getCatalogName();
|
return this.tableMetaDataContext.getSchemaName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +146,14 @@ public abstract class AbstractJdbcInsert {
|
||||||
*/
|
*/
|
||||||
public void setCatalogName(String catalogName) {
|
public void setCatalogName(String catalogName) {
|
||||||
checkIfConfigurationModificationIsAllowed();
|
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<String> columnNames) {
|
public void setColumnNames(List<String> columnNames) {
|
||||||
checkIfConfigurationModificationIsAllowed();
|
checkIfConfigurationModificationIsAllowed();
|
||||||
declaredColumns.clear();
|
this.declaredColumns.clear();
|
||||||
declaredColumns.addAll(columnNames);
|
this.declaredColumns.addAll(columnNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the names of the columns used
|
* Get the names of the columns used
|
||||||
*/
|
*/
|
||||||
public List<String> getColumnNames() {
|
public List<String> getColumnNames() {
|
||||||
return Collections.unmodifiableList(declaredColumns);
|
return Collections.unmodifiableList(this.declaredColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the names of any generated keys
|
* Get the names of any generated keys
|
||||||
*/
|
*/
|
||||||
public String[] getGeneratedKeyNames() {
|
public String[] getGeneratedKeyNames() {
|
||||||
return generatedKeyNames;
|
return this.generatedKeyNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,32 +209,32 @@ public abstract class AbstractJdbcInsert {
|
||||||
this.tableMetaDataContext.setOverrideIncludeSynonymsDefault(override);
|
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
|
* Get the insert string to be used
|
||||||
*/
|
*/
|
||||||
public String getInsertString() {
|
public String getInsertString() {
|
||||||
return insertString;
|
return this.insertString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the array of {@link java.sql.Types} to be used for insert
|
* Get the array of {@link java.sql.Types} to be used for insert
|
||||||
*/
|
*/
|
||||||
public int[] getInsertTypes() {
|
public int[] getInsertTypes() {
|
||||||
return insertTypes;
|
return this.insertTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link JdbcTemplate} that is configured to be used
|
* Get the {@link JdbcTemplate} that is configured to be used
|
||||||
*/
|
*/
|
||||||
protected JdbcTemplate getJdbcTemplate() {
|
protected JdbcTemplate getJdbcTemplate() {
|
||||||
return jdbcTemplate;
|
return this.jdbcTemplate;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary
|
|
||||||
*/
|
|
||||||
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
|
||||||
this.tableMetaDataContext.setNativeJdbcExtractor(nativeJdbcExtractor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue