Skip to content

Commit

Permalink
Pass correct SqlParameterSource to NamedParameterJdbcTemplate in Defa…
Browse files Browse the repository at this point in the history
…ultJdbcClient

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
  • Loading branch information
making authored and sbrannen committed Sep 10, 2023
1 parent 436c713 commit 588b5a4
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public <T> MappedQuerySpec<T> query(RowMapper<T> rowMapper) {
@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);
Expand All @@ -215,7 +215,7 @@ public void query(RowCallbackHandler rch) {
@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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

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;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -128,6 +131,33 @@ public void testQueryWithResultSetExtractor() throws SQLException {
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);
Expand Down Expand Up @@ -178,6 +208,33 @@ public void testQueryWithRowCallbackHandler() throws SQLException {
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);
Expand Down

0 comments on commit 588b5a4

Please sign in to comment.