Skip to content

Commit 3d28c02

Browse files
committed
Handle JDBC warnings in case of a statement exception as well
Closes gh-23106 (cherry picked from commit 3b899fe)
1 parent 3444892 commit 3d28c02

File tree

2 files changed

+67
-14
lines changed

2 files changed

+67
-14
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/SQLWarningException.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -44,11 +44,22 @@ public SQLWarningException(String msg, SQLWarning ex) {
4444
super(msg, ex);
4545
}
4646

47+
4748
/**
48-
* Return the underlying SQLWarning.
49+
* Return the underlying {@link SQLWarning}.
50+
* @since 5.3.29
4951
*/
50-
public SQLWarning SQLWarning() {
52+
public SQLWarning getSQLWarning() {
5153
return (SQLWarning) getCause();
5254
}
5355

56+
/**
57+
* Return the underlying {@link SQLWarning}.
58+
* @deprecated as of 5.3.29, in favor of {@link #getSQLWarning()}
59+
*/
60+
@Deprecated
61+
public SQLWarning SQLWarning() {
62+
return getSQLWarning();
63+
}
64+
5465
}

spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -187,12 +187,14 @@ public JdbcTemplate(DataSource dataSource, boolean lazyInit) {
187187

188188

189189
/**
190-
* Set whether we want to ignore SQLWarnings.
191-
* <p>Default is "true", swallowing and logging all warnings. Switch this flag
192-
* to "false" to make the JdbcTemplate throw an SQLWarningException instead.
190+
* Set whether we want to ignore JDBC statement warnings ({@link SQLWarning}).
191+
* <p>Default is {@code true}, swallowing and logging all warnings. Switch this flag to
192+
* {@code false} to make this JdbcTemplate throw a {@link SQLWarningException} instead
193+
* (or chain the {@link SQLWarning} into the primary {@link SQLException}, if any).
194+
* @see Statement#getWarnings()
193195
* @see java.sql.SQLWarning
194196
* @see org.springframework.jdbc.SQLWarningException
195-
* @see #handleWarnings
197+
* @see #handleWarnings(Statement)
196198
*/
197199
public void setIgnoreWarnings(boolean ignoreWarnings) {
198200
this.ignoreWarnings = ignoreWarnings;
@@ -385,6 +387,9 @@ private <T> T execute(StatementCallback<T> action, boolean closeResources) throw
385387
catch (SQLException ex) {
386388
// Release Connection early, to avoid potential connection pool deadlock
387389
// in the case when the exception translator hasn't been initialized yet.
390+
if (stmt != null) {
391+
handleWarnings(stmt, ex);
392+
}
388393
String sql = getSql(action);
389394
JdbcUtils.closeStatement(stmt);
390395
stmt = null;
@@ -658,6 +663,9 @@ private <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T>
658663
if (psc instanceof ParameterDisposer) {
659664
((ParameterDisposer) psc).cleanupParameters();
660665
}
666+
if (ps != null) {
667+
handleWarnings(ps, ex);
668+
}
661669
String sql = getSql(psc);
662670
psc = null;
663671
JdbcUtils.closeStatement(ps);
@@ -1197,6 +1205,9 @@ public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T>
11971205
if (csc instanceof ParameterDisposer) {
11981206
((ParameterDisposer) csc).cleanupParameters();
11991207
}
1208+
if (cs != null) {
1209+
handleWarnings(cs, ex);
1210+
}
12001211
String sql = getSql(csc);
12011212
csc = null;
12021213
JdbcUtils.closeStatement(cs);
@@ -1494,13 +1505,44 @@ protected PreparedStatementSetter newArgTypePreparedStatementSetter(Object[] arg
14941505
}
14951506

14961507
/**
1497-
* Throw an SQLWarningException if we're not ignoring warnings,
1498-
* otherwise log the warnings at debug level.
1508+
* Handle warnings before propagating a primary {@code SQLException}
1509+
* from executing the given statement.
1510+
* <p>Calls regular {@link #handleWarnings(Statement)} but catches
1511+
* {@link SQLWarningException} in order to chain the {@link SQLWarning}
1512+
* into the primary exception instead.
14991513
* @param stmt the current JDBC statement
1500-
* @throws SQLWarningException if not ignoring warnings
1501-
* @see org.springframework.jdbc.SQLWarningException
1514+
* @param ex the primary exception after failed statement execution
1515+
* @since 5.3.29
1516+
* @see #handleWarnings(Statement)
1517+
* @see SQLException#setNextException
1518+
*/
1519+
protected void handleWarnings(Statement stmt, SQLException ex) {
1520+
try {
1521+
handleWarnings(stmt);
1522+
}
1523+
catch (SQLWarningException nonIgnoredWarning) {
1524+
ex.setNextException(nonIgnoredWarning.getSQLWarning());
1525+
}
1526+
catch (SQLException warningsEx) {
1527+
logger.debug("Failed to retrieve warnings", warningsEx);
1528+
}
1529+
catch (Throwable warningsEx) {
1530+
logger.debug("Failed to process warnings", warningsEx);
1531+
}
1532+
}
1533+
1534+
/**
1535+
* Handle the warnings for the given JDBC statement, if any.
1536+
* <p>Throws a {@link SQLWarningException} if we're not ignoring warnings,
1537+
* otherwise logs the warnings at debug level.
1538+
* @param stmt the current JDBC statement
1539+
* @throws SQLException in case of warnings retrieval failure
1540+
* @throws SQLWarningException for a concrete warning to raise
1541+
* (when not ignoring warnings)
1542+
* @see #setIgnoreWarnings
1543+
* @see #handleWarnings(SQLWarning)
15021544
*/
1503-
protected void handleWarnings(Statement stmt) throws SQLException {
1545+
protected void handleWarnings(Statement stmt) throws SQLException, SQLWarningException {
15041546
if (isIgnoreWarnings()) {
15051547
if (logger.isDebugEnabled()) {
15061548
SQLWarning warningToLog = stmt.getWarnings();
@@ -1517,7 +1559,7 @@ protected void handleWarnings(Statement stmt) throws SQLException {
15171559
}
15181560

15191561
/**
1520-
* Throw an SQLWarningException if encountering an actual warning.
1562+
* Throw a {@link SQLWarningException} if encountering an actual warning.
15211563
* @param warning the warnings object from the current statement.
15221564
* May be {@code null}, in which case this method does nothing.
15231565
* @throws SQLWarningException in case of an actual warning to be raised

0 commit comments

Comments
 (0)