diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java
index 8b570c2b10..16c7b8e0a8 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/CompositeDatabasePopulator.java
@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.jdbc.datasource.init;
import java.sql.Connection;
import java.sql.SQLException;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -44,7 +46,7 @@ public class CompositeDatabasePopulator implements DatabasePopulator {
}
/**
- * Add a populator to the list of delegates.
+ * Add one or more populators to the list of delegates.
*/
public void addPopulators(DatabasePopulator... populators) {
this.populators.addAll(Arrays.asList(populators));
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java
index 1e30251a42..d7e6d550f6 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.java
@@ -31,7 +31,12 @@ import java.sql.SQLException;
public interface DatabasePopulator {
/**
- * Populate the database using the JDBC connection provided.
+ * Populate the database using the provided JDBC connection.
+ *
Concrete implementations may throw an {@link SQLException} if
+ * an error is encountered but are strongly encouraged to throw a
+ * specific {@link ScriptException} instead. For example, Spring's
+ * {@link ResourceDatabasePopulator} and {@link DatabasePopulatorUtils} wrap
+ * all {@code SQLExceptions} in {@code ScriptExceptions}.
* @param connection the JDBC connection to use to populate the db; already
* configured and ready to use
* @throws SQLException if an unrecoverable data access exception occurs
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java
index 8f4189a421..00f46992ab 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.java
@@ -17,7 +17,6 @@
package org.springframework.jdbc.datasource.init;
import java.sql.Connection;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -183,7 +182,7 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
* {@inheritDoc}
*/
@Override
- public void populate(Connection connection) throws SQLException, ScriptException {
+ public void populate(Connection connection) throws ScriptException {
for (Resource script : this.scripts) {
ScriptUtils.executeSqlScript(connection, encodeScript(script), this.continueOnError,
this.ignoreFailedDrops, this.commentPrefix, this.separator, this.blockCommentStartDelimiter,
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
index 68918f5150..364bfe7136 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptUtils.java
@@ -99,6 +99,7 @@ public abstract class ScriptUtils {
* @param script the SQL script
* @param separator character separating each statement — typically a ';'
* @param statements the list that will contain the individual statements
+ * @throws ScriptException if an error occurred while splitting the SQL script
* @see #splitSqlScript(String, String, List)
* @see #splitSqlScript(EncodedResource, String, String, String, String, String, List)
*/
@@ -121,6 +122,7 @@ public abstract class ScriptUtils {
* @param script the SQL script
* @param separator text separating each statement — typically a ';' or newline character
* @param statements the list that will contain the individual statements
+ * @throws ScriptException if an error occurred while splitting the SQL script
* @see #splitSqlScript(String, char, List)
* @see #splitSqlScript(EncodedResource, String, String, String, String, String, List)
*/
@@ -151,6 +153,7 @@ public abstract class ScriptUtils {
* @param blockCommentEndDelimiter the end block comment delimiter;
* never {@code null} or empty
* @param statements the list that will contain the individual statements
+ * @throws ScriptException if an error occurred while splitting the SQL script
*/
public static void splitSqlScript(EncodedResource resource, String script, String separator, String commentPrefix,
String blockCommentStartDelimiter, String blockCommentEndDelimiter, List statements)
@@ -257,6 +260,7 @@ public abstract class ScriptUtils {
* typically "--"
* @param separator the statement separator in the SQL script — typically ";"
* @return a {@code String} containing the script lines
+ * @throws IOException in case of I/O errors
*/
private static String readScript(EncodedResource resource, String commentPrefix, String separator)
throws IOException {
@@ -282,6 +286,7 @@ public abstract class ScriptUtils {
* typically "--"
* @param separator the statement separator in the SQL script — typically ";"
* @return a {@code String} containing the script lines
+ * @throws IOException in case of I/O errors
*/
public static String readScript(LineNumberReader lineNumberReader, String commentPrefix, String separator)
throws IOException {
@@ -344,13 +349,14 @@ public abstract class ScriptUtils {
* configured and ready to use
* @param resource the resource to load the SQL script from; encoded with the
* current platform's default encoding
+ * @throws ScriptException if an error occurred while executing the SQL script
* @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String)
* @see #DEFAULT_COMMENT_PREFIX
* @see #DEFAULT_STATEMENT_SEPARATOR
* @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER
* @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER
*/
- public static void executeSqlScript(Connection connection, Resource resource) throws SQLException, ScriptException {
+ public static void executeSqlScript(Connection connection, Resource resource) throws ScriptException {
executeSqlScript(connection, new EncodedResource(resource));
}
@@ -364,14 +370,14 @@ public abstract class ScriptUtils {
* configured and ready to use
* @param resource the resource (potentially associated with a specific encoding)
* to load the SQL script from
+ * @throws ScriptException if an error occurred while executing the SQL script
* @see #executeSqlScript(Connection, EncodedResource, boolean, boolean, String, String, String, String)
* @see #DEFAULT_COMMENT_PREFIX
* @see #DEFAULT_STATEMENT_SEPARATOR
* @see #DEFAULT_BLOCK_COMMENT_START_DELIMITER
* @see #DEFAULT_BLOCK_COMMENT_END_DELIMITER
*/
- public static void executeSqlScript(Connection connection, EncodedResource resource) throws SQLException,
- ScriptException {
+ public static void executeSqlScript(Connection connection, EncodedResource resource) throws ScriptException {
executeSqlScript(connection, resource, false, false, DEFAULT_COMMENT_PREFIX, DEFAULT_STATEMENT_SEPARATOR,
DEFAULT_BLOCK_COMMENT_START_DELIMITER, DEFAULT_BLOCK_COMMENT_END_DELIMITER);
}
@@ -398,71 +404,83 @@ public abstract class ScriptUtils {
* {@code null} or empty
* @param blockCommentEndDelimiter the end block comment delimiter; never
* {@code null} or empty
+ * @throws ScriptException if an error occurred while executing the SQL script
*/
public static void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError,
boolean ignoreFailedDrops, String commentPrefix, String separator, String blockCommentStartDelimiter,
- String blockCommentEndDelimiter) throws SQLException, ScriptException {
+ String blockCommentEndDelimiter) throws ScriptException {
- if (logger.isInfoEnabled()) {
- logger.info("Executing SQL script from " + resource);
- }
- long startTime = System.currentTimeMillis();
- List statements = new LinkedList();
- String script;
try {
- script = readScript(resource, commentPrefix, separator);
- }
- catch (IOException ex) {
- throw new CannotReadScriptException(resource, ex);
- }
+ if (logger.isInfoEnabled()) {
+ logger.info("Executing SQL script from " + resource);
+ }
- if (separator == null) {
- separator = DEFAULT_STATEMENT_SEPARATOR;
- }
- if (!containsSqlScriptDelimiters(script, separator)) {
- separator = FALLBACK_STATEMENT_SEPARATOR;
- }
+ long startTime = System.currentTimeMillis();
+ List statements = new LinkedList();
+ String script;
+ try {
+ script = readScript(resource, commentPrefix, separator);
+ }
+ catch (IOException ex) {
+ throw new CannotReadScriptException(resource, ex);
+ }
- splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter,
- blockCommentEndDelimiter, statements);
- int lineNumber = 0;
- Statement stmt = connection.createStatement();
- try {
- for (String statement : statements) {
- lineNumber++;
- try {
- stmt.execute(statement);
- int rowsAffected = stmt.getUpdateCount();
- if (logger.isDebugEnabled()) {
- logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
- }
- }
- catch (SQLException ex) {
- boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop");
- if (continueOnError || (dropStatement && ignoreFailedDrops)) {
+ if (separator == null) {
+ separator = DEFAULT_STATEMENT_SEPARATOR;
+ }
+ if (!containsSqlScriptDelimiters(script, separator)) {
+ separator = FALLBACK_STATEMENT_SEPARATOR;
+ }
+
+ splitSqlScript(resource, script, separator, commentPrefix, blockCommentStartDelimiter,
+ blockCommentEndDelimiter, statements);
+ int lineNumber = 0;
+ Statement stmt = connection.createStatement();
+ try {
+ for (String statement : statements) {
+ lineNumber++;
+ try {
+ stmt.execute(statement);
+ int rowsAffected = stmt.getUpdateCount();
if (logger.isDebugEnabled()) {
- logger.debug("Failed to execute SQL script statement at line " + lineNumber
- + " of resource " + resource + ": " + statement, ex);
+ logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
}
}
- else {
- throw new ScriptStatementFailedException(statement, lineNumber, resource, ex);
+ catch (SQLException ex) {
+ boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop");
+ if (continueOnError || (dropStatement && ignoreFailedDrops)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Failed to execute SQL script statement at line " + lineNumber
+ + " of resource " + resource + ": " + statement, ex);
+ }
+ }
+ else {
+ throw new ScriptStatementFailedException(statement, lineNumber, resource, ex);
+ }
}
}
}
- }
- finally {
- try {
- stmt.close();
+ finally {
+ try {
+ stmt.close();
+ }
+ catch (Throwable ex) {
+ logger.debug("Could not close JDBC Statement", ex);
+ }
}
- catch (Throwable ex) {
- logger.debug("Could not close JDBC Statement", ex);
- }
- }
- long elapsedTime = System.currentTimeMillis() - startTime;
- if (logger.isInfoEnabled()) {
- logger.info("Executed SQL script from " + resource + " in " + elapsedTime + " ms.");
+ long elapsedTime = System.currentTimeMillis() - startTime;
+ if (logger.isInfoEnabled()) {
+ logger.info("Executed SQL script from " + resource + " in " + elapsedTime + " ms.");
+ }
+ }
+ catch (Exception ex) {
+ if (ex instanceof ScriptException) {
+ throw (ScriptException) ex;
+ }
+
+ throw new UncategorizedScriptException(
+ "Failed to execute database script from resource [" + resource + "]", ex);
}
}