Allow SELECT statements in ResourceDatabasePopulator

ResourceDatabasePopulator is a component that underlies the database
initialization support within Spring's jdbc: namespace, e.g.:

    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script execution="INIT" location="classpath:init.sql"/>
    </jdbc:initialize-database>

Prior to this commit, ResourceDatabasePopulator#executeSqlScript's use
of Statement#executeUpdate(sql) precluded the possibility of SELECT
statements because returning a result is not permitted by this method
and results in an exception being thrown.

Whether this behavior is a function of the JDBC specification or an
idiosyncracy of certain implementations does not matter as the issue
can be worked around entirely. This commit eliminates use
of #executeUpdate(sql) in favor of #execute(sql) followed by a call
to #getUpdateCount, effectively allowing any kind of SQL statement to
be executed during database initialization.

Issue: SPR-8932
This commit is contained in:
Thomas Risberg 2012-02-03 16:41:57 -05:00 committed by Chris Beams
parent 025b8abfaf
commit 2ffa4725cd
3 changed files with 23 additions and 6 deletions

View File

@ -181,9 +181,10 @@ public class ResourceDatabasePopulator implements DatabasePopulator {
for (String statement : statements) {
lineNumber++;
try {
int rowsAffected = stmt.executeUpdate(statement);
stmt.execute(statement);
int rowsAffected = stmt.getUpdateCount();
if (logger.isDebugEnabled()) {
logger.debug(rowsAffected + " rows affected by SQL: " + statement);
logger.debug(rowsAffected + " returned as updateCount for SQL: " + statement);
}
}
catch (SQLException ex) {

View File

@ -20,8 +20,6 @@ import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Test;
import org.springframework.core.io.ClassRelativeResourceLoader;
@ -49,7 +47,7 @@ public class DatabasePopulatorTests {
assertEquals(name, jdbcTemplate.queryForObject("select NAME from T_TEST", String.class));
}
private void assertUsersDatabaseCreated(DataSource db) {
private void assertUsersDatabaseCreated() {
assertEquals("Sam", jdbcTemplate.queryForObject("select first_name from users where last_name = 'Brannen'",
String.class));
}
@ -191,7 +189,22 @@ public class DatabasePopulatorTests {
connection.close();
}
assertUsersDatabaseCreated(db);
assertUsersDatabaseCreated();
}
@Test
public void testBuildWithSelectStatements() throws Exception {
databasePopulator.addScript(resourceLoader.getResource("db-schema.sql"));
databasePopulator.addScript(resourceLoader.getResource("db-test-data-select.sql"));
Connection connection = db.getConnection();
try {
databasePopulator.populate(connection);
} finally {
connection.close();
}
assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Keith'"));
assertEquals(1, jdbcTemplate.queryForInt("select COUNT(NAME) from T_TEST where NAME='Dave'"));
}
}

View File

@ -0,0 +1,3 @@
insert into T_TEST (NAME) values ('Keith');
insert into T_TEST (NAME) values ('Dave');
select NAME from T_TEST where NAME = 'Keith';