Browse Source

Pass correct SqlParameterSource to NamedParameterJdbcTemplate in DefaultJdbcClient

Prior to this commit, when using RowCallbackHandler or ResultSetExtractor in JdbcClient
and passing a parameter to paramSource(), an exception was thrown stating "No value
supplied for the SQL parameter 'xxxxxx'" because the SqlParameterSource used internally
was the wrong one.

Closes gh-31195
pull/31202/head
Toshiaki Maki 1 year ago committed by Sam Brannen
parent
commit
588b5a45f8
  1. 4
      spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java
  2. 57
      spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientNamedParameterTests.java

4
spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java

@ -205,7 +205,7 @@ final class DefaultJdbcClient implements JdbcClient { @@ -205,7 +205,7 @@ final class DefaultJdbcClient implements JdbcClient {
@Override
public void query(RowCallbackHandler rch) {
if (useNamedParams()) {
namedParamOps.query(this.sql, this.namedParams, rch);
namedParamOps.query(this.sql, this.namedParamSource, rch);
}
else {
classicOps.query(getPreparedStatementCreatorForIndexedParams(), rch);
@ -215,7 +215,7 @@ final class DefaultJdbcClient implements JdbcClient { @@ -215,7 +215,7 @@ final class DefaultJdbcClient implements JdbcClient {
@Override
public <T> T query(ResultSetExtractor<T> rse) {
T result = (useNamedParams() ?
namedParamOps.query(this.sql, this.namedParams, rse) :
namedParamOps.query(this.sql, this.namedParamSource, rse) :
classicOps.query(getPreparedStatementCreatorForIndexedParams(), rse));
Assert.state(result != null, "No result from ResultSetExtractor");
return result;

57
spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientNamedParameterTests.java

@ -38,6 +38,7 @@ import org.junit.jupiter.api.Test; @@ -38,6 +38,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.jdbc.Customer;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
@ -89,6 +90,8 @@ public class JdbcClientNamedParameterTests { @@ -89,6 +90,8 @@ public class JdbcClientNamedParameterTests {
private Map<String, Object> params = new HashMap<>();
private MapSqlParameterSource paramSource = new MapSqlParameterSource();
@BeforeEach
public void setup() throws Exception {
@ -128,6 +131,33 @@ public class JdbcClientNamedParameterTests { @@ -128,6 +131,33 @@ public class JdbcClientNamedParameterTests {
verify(connection).close();
}
@Test
public void testQueryWithResultSetExtractorParameterSource() throws SQLException {
given(resultSet.next()).willReturn(true);
given(resultSet.getInt("id")).willReturn(1);
given(resultSet.getString("forename")).willReturn("rod");
paramSource.addValue("id", new SqlParameterValue(Types.DECIMAL, 1));
paramSource.addValue("country", "UK");
Customer cust = client.sql(SELECT_NAMED_PARAMETERS).paramSource(paramSource).query(
rs -> {
rs.next();
Customer cust1 = new Customer();
cust1.setId(rs.getInt(COLUMN_NAMES[0]));
cust1.setForename(rs.getString(COLUMN_NAMES[1]));
return cust1;
});
assertThat(cust.getId()).as("Customer id was assigned correctly").isEqualTo(1);
assertThat(cust.getForename()).as("Customer forename was assigned correctly").isEqualTo("rod");
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryWithResultSetExtractorNoParameters() throws SQLException {
given(resultSet.next()).willReturn(true);
@ -178,6 +208,33 @@ public class JdbcClientNamedParameterTests { @@ -178,6 +208,33 @@ public class JdbcClientNamedParameterTests {
verify(connection).close();
}
@Test
public void testQueryWithRowCallbackHandlerParameterSource() throws SQLException {
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt("id")).willReturn(1);
given(resultSet.getString("forename")).willReturn("rod");
paramSource.addValue("id", new SqlParameterValue(Types.DECIMAL, 1));
paramSource.addValue("country", "UK");
final List<Customer> customers = new ArrayList<>();
client.sql(SELECT_NAMED_PARAMETERS).paramSource(paramSource).query(rs -> {
Customer cust = new Customer();
cust.setId(rs.getInt(COLUMN_NAMES[0]));
cust.setForename(rs.getString(COLUMN_NAMES[1]));
customers.add(cust);
});
assertThat(customers).hasSize(1);
assertThat(customers.get(0).getId()).as("Customer id was assigned correctly").isEqualTo(1);
assertThat(customers.get(0).getForename()).as("Customer forename was assigned correctly").isEqualTo("rod");
verify(connection).prepareStatement(SELECT_NAMED_PARAMETERS_PARSED);
verify(preparedStatement).setObject(1, 1, Types.DECIMAL);
verify(preparedStatement).setString(2, "UK");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryWithRowCallbackHandlerNoParameters() throws SQLException {
given(resultSet.next()).willReturn(true, false);

Loading…
Cancel
Save