Protect against null return value from DataSource.getConnection()
Issue: SPR-15641
This commit is contained in:
parent
bf66f45283
commit
ee5fa2633a
|
@ -25,10 +25,20 @@ import org.springframework.lang.Nullable;
|
||||||
* Fatal exception thrown when we can't connect to an RDBMS using JDBC.
|
* Fatal exception thrown when we can't connect to an RDBMS using JDBC.
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class CannotGetJdbcConnectionException extends DataAccessResourceFailureException {
|
public class CannotGetJdbcConnectionException extends DataAccessResourceFailureException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for CannotGetJdbcConnectionException.
|
||||||
|
* @param msg the detail message
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public CannotGetJdbcConnectionException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for CannotGetJdbcConnectionException.
|
* Constructor for CannotGetJdbcConnectionException.
|
||||||
* @param msg the detail message
|
* @param msg the detail message
|
||||||
|
|
|
@ -78,7 +78,10 @@ public abstract class DataSourceUtils {
|
||||||
return doGetConnection(dataSource);
|
return doGetConnection(dataSource);
|
||||||
}
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
|
throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", ex);
|
||||||
|
}
|
||||||
|
catch (IllegalStateException ex) {
|
||||||
|
throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection: " + ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,14 +105,14 @@ public abstract class DataSourceUtils {
|
||||||
conHolder.requested();
|
conHolder.requested();
|
||||||
if (!conHolder.hasConnection()) {
|
if (!conHolder.hasConnection()) {
|
||||||
logger.debug("Fetching resumed JDBC Connection from DataSource");
|
logger.debug("Fetching resumed JDBC Connection from DataSource");
|
||||||
conHolder.setConnection(dataSource.getConnection());
|
conHolder.setConnection(fetchConnection(dataSource));
|
||||||
}
|
}
|
||||||
return conHolder.getConnection();
|
return conHolder.getConnection();
|
||||||
}
|
}
|
||||||
// Else we either got no holder or an empty thread-bound holder here.
|
// Else we either got no holder or an empty thread-bound holder here.
|
||||||
|
|
||||||
logger.debug("Fetching JDBC Connection from DataSource");
|
logger.debug("Fetching JDBC Connection from DataSource");
|
||||||
Connection con = dataSource.getConnection();
|
Connection con = fetchConnection(dataSource);
|
||||||
|
|
||||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
logger.debug("Registering transaction synchronization for JDBC Connection");
|
logger.debug("Registering transaction synchronization for JDBC Connection");
|
||||||
|
@ -134,6 +137,24 @@ public abstract class DataSourceUtils {
|
||||||
return con;
|
return con;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually fetch a {@link Connection} from the given {@link DataSource},
|
||||||
|
* defensively turning an unexpected {@code null} return value from
|
||||||
|
* {@link DataSource#getConnection()} into an {@link IllegalStateException}.
|
||||||
|
* @param dataSource the DataSource to obtain Connections from
|
||||||
|
* @return a JDBC Connection from the given DataSource (never {@code null})
|
||||||
|
* @throws SQLException if thrown by JDBC methods
|
||||||
|
* @throws IllegalStateException if the DataSource returned a null value
|
||||||
|
* @see DataSource#getConnection()
|
||||||
|
*/
|
||||||
|
private static Connection fetchConnection(DataSource dataSource) throws SQLException {
|
||||||
|
Connection con = dataSource.getConnection();
|
||||||
|
if (con == null) {
|
||||||
|
throw new IllegalStateException("DataSource returned null from getConnection(): " + dataSource);
|
||||||
|
}
|
||||||
|
return con;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the given Connection with the given transaction semantics.
|
* Prepare the given Connection with the given transaction semantics.
|
||||||
* @param con the Connection to prepare
|
* @param con the Connection to prepare
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 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.
|
||||||
|
@ -40,8 +40,10 @@ abstract class AbstractEmbeddedDatabaseConfigurer implements EmbeddedDatabaseCon
|
||||||
Connection con = null;
|
Connection con = null;
|
||||||
try {
|
try {
|
||||||
con = dataSource.getConnection();
|
con = dataSource.getConnection();
|
||||||
|
if (con != null) {
|
||||||
con.createStatement().execute("SHUTDOWN");
|
con.createStatement().execute("SHUTDOWN");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (SQLException ex) {
|
catch (SQLException ex) {
|
||||||
logger.warn("Could not shut down embedded database", ex);
|
logger.warn("Could not shut down embedded database", ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 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.
|
||||||
|
@ -112,6 +112,10 @@ public class DatabaseStartupValidator implements InitializingBean {
|
||||||
Statement stmt = null;
|
Statement stmt = null;
|
||||||
try {
|
try {
|
||||||
con = this.dataSource.getConnection();
|
con = this.dataSource.getConnection();
|
||||||
|
if (con == null) {
|
||||||
|
throw new CannotGetJdbcConnectionException("Failed to execute validation query: " +
|
||||||
|
"DataSource returned null from getConnection(): " + this.dataSource);
|
||||||
|
}
|
||||||
stmt = con.createStatement();
|
stmt = con.createStatement();
|
||||||
stmt.execute(this.validationQuery);
|
stmt.execute(this.validationQuery);
|
||||||
validated = true;
|
validated = true;
|
||||||
|
|
Loading…
Reference in New Issue