Skip to content

Commit 5f51728

Browse files
committed
Retry DatabaseMetaData retrieval if access to transactional connection fails
Closes gh-25681
1 parent 9f2d8d4 commit 5f51728

File tree

1 file changed

+28
-10
lines changed
  • spring-jdbc/src/main/java/org/springframework/jdbc/support

1 file changed

+28
-10
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.java

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -298,26 +298,44 @@ else if (obj instanceof java.sql.Date) {
298298

299299
/**
300300
* Extract database meta-data via the given DatabaseMetaDataCallback.
301-
* <p>This method will open a connection to the database and retrieve the database meta-data.
302-
* Since this method is called before the exception translation feature is configured for
303-
* a datasource, this method can not rely on the SQLException translation functionality.
304-
* <p>Any exceptions will be wrapped in a MetaDataAccessException. This is a checked exception
305-
* and any calling code should catch and handle this exception. You can just log the
306-
* error and hope for the best, but there is probably a more serious error that will
307-
* reappear when you try to access the database again.
301+
* <p>This method will open a connection to the database and retrieve its meta-data.
302+
* Since this method is called before the exception translation feature is configured
303+
* for a DataSource, this method can not rely on SQLException translation itself.
304+
* <p>Any exceptions will be wrapped in a MetaDataAccessException. This is a checked
305+
* exception and any calling code should catch and handle this exception. You can just
306+
* log the error and hope for the best, but there is probably a more serious error that
307+
* will reappear when you try to access the database again.
308308
* @param dataSource the DataSource to extract meta-data for
309309
* @param action callback that will do the actual work
310310
* @return object containing the extracted information, as returned by
311311
* the DatabaseMetaDataCallback's {@code processMetaData} method
312312
* @throws MetaDataAccessException if meta-data access failed
313+
* @see java.sql.DatabaseMetaData
313314
*/
314315
public static Object extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback action)
315316
throws MetaDataAccessException {
316317

317318
Connection con = null;
318319
try {
319320
con = DataSourceUtils.getConnection(dataSource);
320-
DatabaseMetaData metaData = con.getMetaData();
321+
DatabaseMetaData metaData;
322+
try {
323+
metaData = con.getMetaData();
324+
}
325+
catch (SQLException ex) {
326+
if (DataSourceUtils.isConnectionTransactional(con, dataSource)) {
327+
// Probably a closed thread-bound Connection - retry against fresh Connection
328+
DataSourceUtils.releaseConnection(con, dataSource);
329+
con = null;
330+
logger.debug("Failed to obtain DatabaseMetaData from transactional Connection - " +
331+
"retrying against fresh Connection", ex);
332+
con = dataSource.getConnection();
333+
metaData = con.getMetaData();
334+
}
335+
else {
336+
throw ex;
337+
}
338+
}
321339
if (metaData == null) {
322340
// should only happen in test environments
323341
throw new MetaDataAccessException("DatabaseMetaData returned by Connection [" + con + "] was null");
@@ -446,9 +464,9 @@ public static boolean isNumeric(int sqlType) {
446464
* expressed in the JDBC 4.0 specification:
447465
* <p><i>columnLabel - the label for the column specified with the SQL AS clause.
448466
* If the SQL AS clause was not specified, then the label is the name of the column</i>.
449-
* @return the column name to use
450467
* @param resultSetMetaData the current meta-data to use
451468
* @param columnIndex the index of the column for the look up
469+
* @return the column name to use
452470
* @throws SQLException in case of lookup failure
453471
*/
454472
public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException {

0 commit comments

Comments
 (0)