|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2018 the original author or authors. |
| 2 | + * Copyright 2002-2020 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -305,30 +305,44 @@ else if (obj instanceof java.sql.Date) {
|
305 | 305 |
|
306 | 306 | /**
|
307 | 307 | * Extract database meta-data via the given DatabaseMetaDataCallback.
|
308 |
| - * <p>This method will open a connection to the database and retrieve the database meta-data. |
309 |
| - * Since this method is called before the exception translation feature is configured for |
310 |
| - * a datasource, this method can not rely on the SQLException translation functionality. |
311 |
| - * <p>Any exceptions will be wrapped in a MetaDataAccessException. This is a checked exception |
312 |
| - * and any calling code should catch and handle this exception. You can just log the |
313 |
| - * error and hope for the best, but there is probably a more serious error that will |
314 |
| - * reappear when you try to access the database again. |
| 308 | + * <p>This method will open a connection to the database and retrieve its meta-data. |
| 309 | + * Since this method is called before the exception translation feature is configured |
| 310 | + * for a DataSource, this method can not rely on SQLException translation itself. |
| 311 | + * <p>Any exceptions will be wrapped in a MetaDataAccessException. This is a checked |
| 312 | + * exception and any calling code should catch and handle this exception. You can just |
| 313 | + * log the error and hope for the best, but there is probably a more serious error that |
| 314 | + * will reappear when you try to access the database again. |
315 | 315 | * @param dataSource the DataSource to extract meta-data for
|
316 | 316 | * @param action callback that will do the actual work
|
317 | 317 | * @return object containing the extracted information, as returned by
|
318 | 318 | * the DatabaseMetaDataCallback's {@code processMetaData} method
|
319 | 319 | * @throws MetaDataAccessException if meta-data access failed
|
| 320 | + * @see java.sql.DatabaseMetaData |
320 | 321 | */
|
321 | 322 | public static Object extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback action)
|
322 | 323 | throws MetaDataAccessException {
|
323 | 324 |
|
324 | 325 | Connection con = null;
|
325 | 326 | try {
|
326 | 327 | con = DataSourceUtils.getConnection(dataSource);
|
327 |
| - if (con == null) { |
328 |
| - // should only happen in test environments |
329 |
| - throw new MetaDataAccessException("Connection returned by DataSource [" + dataSource + "] was null"); |
| 328 | + DatabaseMetaData metaData; |
| 329 | + try { |
| 330 | + metaData = con.getMetaData(); |
| 331 | + } |
| 332 | + catch (SQLException ex) { |
| 333 | + if (DataSourceUtils.isConnectionTransactional(con, dataSource)) { |
| 334 | + // Probably a closed thread-bound Connection - retry against fresh Connection |
| 335 | + DataSourceUtils.releaseConnection(con, dataSource); |
| 336 | + con = null; |
| 337 | + logger.debug("Failed to obtain DatabaseMetaData from transactional Connection - " + |
| 338 | + "retrying against fresh Connection", ex); |
| 339 | + con = dataSource.getConnection(); |
| 340 | + metaData = con.getMetaData(); |
| 341 | + } |
| 342 | + else { |
| 343 | + throw ex; |
| 344 | + } |
330 | 345 | }
|
331 |
| - DatabaseMetaData metaData = con.getMetaData(); |
332 | 346 | if (metaData == null) {
|
333 | 347 | // should only happen in test environments
|
334 | 348 | throw new MetaDataAccessException("DatabaseMetaData returned by Connection [" + con + "] was null");
|
@@ -458,9 +472,9 @@ public static boolean isNumeric(int sqlType) {
|
458 | 472 | * expressed in the JDBC 4.0 specification:
|
459 | 473 | * <p><i>columnLabel - the label for the column specified with the SQL AS clause.
|
460 | 474 | * If the SQL AS clause was not specified, then the label is the name of the column</i>.
|
461 |
| - * @return the column name to use |
462 | 475 | * @param resultSetMetaData the current meta-data to use
|
463 | 476 | * @param columnIndex the index of the column for the look up
|
| 477 | + * @return the column name to use |
464 | 478 | * @throws SQLException in case of lookup failure
|
465 | 479 | */
|
466 | 480 | public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException {
|
|
0 commit comments