Skip to content

Commit 92eb99a

Browse files
committed
Favor ScriptException over SQLException
In ScriptUtils and related classes, SQLExceptions are now caught and wrapped in ScriptExceptions wherever feasible. Affected "throws" declarations have also been revised as appropriate. Issue: SPR-11564
1 parent cf290ab commit 92eb99a

File tree

4 files changed

+79
-55
lines changed

4 files changed

+79
-55
lines changed

spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16+
1617
package org.springframework.jdbc.datasource.init;
1718

1819
import java.sql.Connection;
1920
import java.sql.SQLException;
21+
2022
import java.util.ArrayList;
2123
import java.util.Arrays;
2224
import java.util.List;
@@ -44,7 +46,7 @@ public void setPopulators(DatabasePopulator... populators) {
4446
}
4547

4648
/**
47-
* Add a populator to the list of delegates.
49+
* Add one or more populators to the list of delegates.
4850
*/
4951
public void addPopulators(DatabasePopulator... populators) {
5052
this.populators.addAll(Arrays.asList(populators));

spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@
3131
public interface DatabasePopulator {
3232

3333
/**
34-
* Populate the database using the JDBC connection provided.
34+
* Populate the database using the provided JDBC connection.
35+
* <p>Concrete implementations <em>may</em> throw an {@link SQLException} if
36+
* an error is encountered but are <em>strongly encouraged</em> to throw a
37+
* specific {@link ScriptException} instead. For example, Spring's
38+
* {@link ResourceDatabasePopulator} and {@link DatabasePopulatorUtils} wrap
39+
* all {@code SQLExceptions} in {@code ScriptExceptions}.
3540
* @param connection the JDBC connection to use to populate the db; already
3641
* configured and ready to use
3742
* @throws SQLException if an unrecoverable data access exception occurs

spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.jdbc.datasource.init;
1818

1919
import java.sql.Connection;
20-
import java.sql.SQLException;
2120
import java.util.ArrayList;
2221
import java.util.Arrays;
2322
import java.util.List;
@@ -183,7 +182,7 @@ public void setIgnoreFailedDrops(boolean ignoreFailedDrops) {
183182
* {@inheritDoc}
184183
*/
185184
@Override
186-
public void populate(Connection connection) throws SQLException, ScriptException {
185+
public void populate(Connection connection) throws ScriptException {
187186
for (Resource script : this.scripts) {
188187
ScriptUtils.executeSqlScript(connection, encodeScript(script), this.continueOnError,
189188
this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter,

spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ private ScriptUtils() {
9999
* @param script the SQL script
100100
* @param separator character separating each statement &mdash; typically a ';'
101101
* @param statements the list that will contain the individual statements
102+
* @throws ScriptException if an error occurred while splitting the SQL script
102103
* @see #splitSqlScript(String, String, List)
103104
* @see #splitSqlScript(EncodedResource, String, String, String, String, String, List)
104105
*/
@@ -121,6 +122,7 @@ public static void splitSqlScript(String script, char separator, List<String> st
121122
* @param script the SQL script
122123
* @param separator text separating each statement &mdash; typically a ';' or newline character
123124
* @param statements the list that will contain the individual statements
125+
* @throws ScriptException if an error occurred while splitting the SQL script
124126
* @see #splitSqlScript(String, char, List)
125127
* @see #splitSqlScript(EncodedResource, String, String, String, String, String, List)
126128
*/
@@ -151,6 +153,7 @@ public static void splitSqlScript(String script, String separator, List<String>
151153
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter;
152154
* never {@code null} or empty
153155
* @param statements the list that will contain the individual statements
156+
* @throws ScriptException if an error occurred while splitting the SQL script
154157
*/
155158
public static void splitSqlScript(EncodedResource resource, String script, String separator, String commentPrefix,
156159
String blockCommentStartDelimiter, String blockCommentEndDelimiter, List<String> statements)
@@ -257,6 +260,7 @@ static String readScript(EncodedResource resource) throws IOException {
257260
* typically "--"
258261
* @param separator the statement separator in the SQL script &mdash; typically ";"
259262
* @return a {@code String} containing the script lines
263+
* @throws IOException in case of I/O errors
260264
*/
261265
private static String readScript(EncodedResource resource, String commentPrefix, String separator)
262266
throws IOException {
@@ -282,6 +286,7 @@ private static String readScript(EncodedResource resource, String commentPrefix,
282286
* typically "--"
283287
* @param separator the statement separator in the SQL script &mdash; typically ";"
284288
* @return a {@code String} containing the script lines
289+
* @throws IOException in case of I/O errors
285290
*/
286291
public static String readScript(LineNumberReader lineNumberReader, String commentPrefix, String separator)
287292
throws IOException {
@@ -344,13 +349,14 @@ public static boolean containsSqlScriptDelimiters(String script, String delim) {
344349
* configured and ready to use
345350
* @param resource the resource to load the SQL script from; encoded with the
346351
* current platform's default encoding
352+
* @throws ScriptException if an error occurred while executing the SQL script
347353
* @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String)
348354
* @see #DEFAULT_COMMENT_PREFIX
349355
* @see #DEFAULT_STATEMENT_SEPARATOR
350356
* @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER
351357
* @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER
352358
*/
353-
public static void executeSqlScript(Connection connection, Resource resource) throws SQLException, ScriptException {
359+
public static void executeSqlScript(Connection connection, Resource resource) throws ScriptException {
354360
executeSqlScript(connection, new EncodedResource(resource));
355361
}
356362

@@ -364,14 +370,14 @@ public static void executeSqlScript(Connection connection, Resource resource) th
364370
* configured and ready to use
365371
* @param resource the resource (potentially associated with a specific encoding)
366372
* to load the SQL script from
373+
* @throws ScriptException if an error occurred while executing the SQL script
367374
* @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String)
368375
* @see #DEFAULT_COMMENT_PREFIX
369376
* @see #DEFAULT_STATEMENT_SEPARATOR
370377
* @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER
371378
* @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER
372379
*/
373-
public static void executeSqlScript(Connection connection, EncodedResource resource) throws SQLException,
374-
ScriptException {
380+
public static void executeSqlScript(Connection connection, EncodedResource resource) throws ScriptException {
375381
executeSqlScript(connection, resource, false, false, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR,
376382
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
377383
}
@@ -398,71 +404,83 @@ public static void executeSqlScript(Connection connection, EncodedResource resou
398404
* {@code null} or empty
399405
* @param blockCommentEndDelimiter the <em>end</em> block comment delimiter; never
400406
* {@code null} or empty
407+
* @throws ScriptException if an error occurred while executing the SQL script
401408
*/
402409
public static void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError,
403410
boolean ignoreFailedDrops, String commentPrefix, String separator, String blockCommentStartDelimiter,
404-
String blockCommentEndDelimiter) throws SQLException, ScriptException {
411+
String blockCommentEndDelimiter) throws ScriptException {
405412

406-
if (logger.isInfoEnabled()) {
407-
logger.info("Executing SQL script from " + resource);
408-
}
409-
long startTime = System.currentTimeMillis();
410-
List<String> statements = new LinkedList<String>();
411-
String script;
412413
try {
413-
script = readScript(resource, commentPrefix, separator);
414-
}
415-
catch (IOException ex) {
416-
throw new CannotReadScriptException(resource, ex);
417-
}
414+
if (logger.isInfoEnabled()) {
415+
logger.info("Executing SQL script from " + resource);
416+
}
418417

419-
if (separator == null) {
420-
separator = DEFAULT_STATEMENT_SEPARATOR;
421-
}
422-
if (!containsSqlScriptDelimiters(script, separator)) {
423-
separator = FALLBACK_STATEMENT_SEPARATOR;
424-
}
418+
long startTime = System.currentTimeMillis();
419+
List<String> statements = new LinkedList<String>();
420+
String script;
421+
try {
422+
script = readScript(resource, commentPrefix, separator);
423+
}
424+
catch (IOException ex) {
425+
throw new CannotReadScriptException(resource, ex);
426+
}
425427

426-
splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter,
427-
blockCommentEndDelimiter, statements);
428-
int lineNumber = 0;
429-
Statement stmt = connection.createStatement();
430-
try {
431-
for (String statement : statements) {
432-
lineNumber++;
433-
try {
434-
stmt.execute(statement);
435-
int rowsAffected = stmt.getUpdateCount();
436-
if (logger.isDebugEnabled()) {
437-
logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
438-
}
439-
}
440-
catch (SQLException ex) {
441-
boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop");
442-
if (continueOnError || (dropStatement && ignoreFailedDrops)) {
428+
if (separator == null) {
429+
separator = DEFAULT_STATEMENT_SEPARATOR;
430+
}
431+
if (!containsSqlScriptDelimiters(script, separator)) {
432+
separator = FALLBACK_STATEMENT_SEPARATOR;
433+
}
434+
435+
splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter,
436+
blockCommentEndDelimiter, statements);
437+
int lineNumber = 0;
438+
Statement stmt = connection.createStatement();
439+
try {
440+
for (String statement : statements) {
441+
lineNumber++;
442+
try {
443+
stmt.execute(statement);
444+
int rowsAffected = stmt.getUpdateCount();
443445
if (logger.isDebugEnabled()) {
444-
logger.debug("Failed to execute SQL script statement at line " + lineNumber
445-
+ " of resource " + resource + ": " + statement, ex);
446+
logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
446447
}
447448
}
448-
else {
449-
throw new ScriptStatementFailedException(statement, lineNumber, resource, ex);
449+
catch (SQLException ex) {
450+
boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop");
451+
if (continueOnError || (dropStatement && ignoreFailedDrops)) {
452+
if (logger.isDebugEnabled()) {
453+
logger.debug("Failed to execute SQL script statement at line " + lineNumber
454+
+ " of resource " + resource + ": " + statement, ex);
455+
}
456+
}
457+
else {
458+
throw new ScriptStatementFailedException(statement, lineNumber, resource, ex);
459+
}
450460
}
451461
}
452462
}
453-
}
454-
finally {
455-
try {
456-
stmt.close();
463+
finally {
464+
try {
465+
stmt.close();
466+
}
467+
catch (Throwable ex) {
468+
logger.debug("Could not close JDBC Statement", ex);
469+
}
457470
}
458-
catch (Throwable ex) {
459-
logger.debug("Could not close JDBC Statement", ex);
471+
472+
long elapsedTime = System.currentTimeMillis() - startTime;
473+
if (logger.isInfoEnabled()) {
474+
logger.info("Executed SQL script from " + resource + " in " + elapsedTime + " ms.");
460475
}
461476
}
477+
catch (Exception ex) {
478+
if (ex instanceof ScriptException) {
479+
throw (ScriptException) ex;
480+
}
462481

463-
long elapsedTime = System.currentTimeMillis() - startTime;
464-
if (logger.isInfoEnabled()) {
465-
logger.info("Executed SQL script from " + resource + " in " + elapsedTime + " ms.");
482+
throw new UncategorizedScriptException(
483+
"Failed to execute database script from resource [" + resource + "]", ex);
466484
}
467485
}
468486

0 commit comments

Comments
 (0)