1
1
/*
2
- * Copyright 2002-2020 the original author or authors.
2
+ * Copyright 2002-2023 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.
@@ -187,12 +187,14 @@ public JdbcTemplate(DataSource dataSource, boolean lazyInit) {
187
187
188
188
189
189
/**
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()
193
195
* @see java.sql.SQLWarning
194
196
* @see org.springframework.jdbc.SQLWarningException
195
- * @see #handleWarnings
197
+ * @see #handleWarnings(Statement)
196
198
*/
197
199
public void setIgnoreWarnings (boolean ignoreWarnings ) {
198
200
this .ignoreWarnings = ignoreWarnings ;
@@ -385,6 +387,9 @@ private <T> T execute(StatementCallback<T> action, boolean closeResources) throw
385
387
catch (SQLException ex ) {
386
388
// Release Connection early, to avoid potential connection pool deadlock
387
389
// in the case when the exception translator hasn't been initialized yet.
390
+ if (stmt != null ) {
391
+ handleWarnings (stmt , ex );
392
+ }
388
393
String sql = getSql (action );
389
394
JdbcUtils .closeStatement (stmt );
390
395
stmt = null ;
@@ -658,6 +663,9 @@ private <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T>
658
663
if (psc instanceof ParameterDisposer ) {
659
664
((ParameterDisposer ) psc ).cleanupParameters ();
660
665
}
666
+ if (ps != null ) {
667
+ handleWarnings (ps , ex );
668
+ }
661
669
String sql = getSql (psc );
662
670
psc = null ;
663
671
JdbcUtils .closeStatement (ps );
@@ -1197,6 +1205,9 @@ public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T>
1197
1205
if (csc instanceof ParameterDisposer ) {
1198
1206
((ParameterDisposer ) csc ).cleanupParameters ();
1199
1207
}
1208
+ if (cs != null ) {
1209
+ handleWarnings (cs , ex );
1210
+ }
1200
1211
String sql = getSql (csc );
1201
1212
csc = null ;
1202
1213
JdbcUtils .closeStatement (cs );
@@ -1494,13 +1505,44 @@ protected PreparedStatementSetter newArgTypePreparedStatementSetter(Object[] arg
1494
1505
}
1495
1506
1496
1507
/**
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.
1499
1513
* @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)
1502
1544
*/
1503
- protected void handleWarnings (Statement stmt ) throws SQLException {
1545
+ protected void handleWarnings (Statement stmt ) throws SQLException , SQLWarningException {
1504
1546
if (isIgnoreWarnings ()) {
1505
1547
if (logger .isDebugEnabled ()) {
1506
1548
SQLWarning warningToLog = stmt .getWarnings ();
@@ -1517,7 +1559,7 @@ protected void handleWarnings(Statement stmt) throws SQLException {
1517
1559
}
1518
1560
1519
1561
/**
1520
- * Throw an SQLWarningException if encountering an actual warning.
1562
+ * Throw a {@link SQLWarningException} if encountering an actual warning.
1521
1563
* @param warning the warnings object from the current statement.
1522
1564
* May be {@code null}, in which case this method does nothing.
1523
1565
* @throws SQLWarningException in case of an actual warning to be raised
0 commit comments