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
This commit is contained in:
		
							parent
							
								
									436c7136e9
								
							
						
					
					
						commit
						588b5a45f8
					
				| 
						 | 
					@ -205,7 +205,7 @@ final class DefaultJdbcClient implements JdbcClient {
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
		public void query(RowCallbackHandler rch) {
 | 
							public void query(RowCallbackHandler rch) {
 | 
				
			||||||
			if (useNamedParams()) {
 | 
								if (useNamedParams()) {
 | 
				
			||||||
				namedParamOps.query(this.sql, this.namedParams, rch);
 | 
									namedParamOps.query(this.sql, this.namedParamSource, rch);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else {
 | 
								else {
 | 
				
			||||||
				classicOps.query(getPreparedStatementCreatorForIndexedParams(), rch);
 | 
									classicOps.query(getPreparedStatementCreatorForIndexedParams(), rch);
 | 
				
			||||||
| 
						 | 
					@ -215,7 +215,7 @@ final class DefaultJdbcClient implements JdbcClient {
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
		public <T> T query(ResultSetExtractor<T> rse) {
 | 
							public <T> T query(ResultSetExtractor<T> rse) {
 | 
				
			||||||
			T result = (useNamedParams() ?
 | 
								T result = (useNamedParams() ?
 | 
				
			||||||
					namedParamOps.query(this.sql, this.namedParams, rse) :
 | 
										namedParamOps.query(this.sql, this.namedParamSource, rse) :
 | 
				
			||||||
					classicOps.query(getPreparedStatementCreatorForIndexedParams(), rse));
 | 
										classicOps.query(getPreparedStatementCreatorForIndexedParams(), rse));
 | 
				
			||||||
			Assert.state(result != null, "No result from ResultSetExtractor");
 | 
								Assert.state(result != null, "No result from ResultSetExtractor");
 | 
				
			||||||
			return result;
 | 
								return result;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,7 @@ import org.junit.jupiter.api.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.springframework.jdbc.Customer;
 | 
					import org.springframework.jdbc.Customer;
 | 
				
			||||||
import org.springframework.jdbc.core.SqlParameterValue;
 | 
					import org.springframework.jdbc.core.SqlParameterValue;
 | 
				
			||||||
 | 
					import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 | 
				
			||||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
 | 
					import org.springframework.jdbc.support.GeneratedKeyHolder;
 | 
				
			||||||
import org.springframework.jdbc.support.KeyHolder;
 | 
					import org.springframework.jdbc.support.KeyHolder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +90,8 @@ public class JdbcClientNamedParameterTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Map<String, Object> params = new HashMap<>();
 | 
						private Map<String, Object> params = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private MapSqlParameterSource paramSource = new MapSqlParameterSource();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@BeforeEach
 | 
						@BeforeEach
 | 
				
			||||||
	public void setup() throws Exception {
 | 
						public void setup() throws Exception {
 | 
				
			||||||
| 
						 | 
					@ -128,6 +131,33 @@ public class JdbcClientNamedParameterTests {
 | 
				
			||||||
		verify(connection).close();
 | 
							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
 | 
						@Test
 | 
				
			||||||
	public void testQueryWithResultSetExtractorNoParameters() throws SQLException {
 | 
						public void testQueryWithResultSetExtractorNoParameters() throws SQLException {
 | 
				
			||||||
		given(resultSet.next()).willReturn(true);
 | 
							given(resultSet.next()).willReturn(true);
 | 
				
			||||||
| 
						 | 
					@ -178,6 +208,33 @@ public class JdbcClientNamedParameterTests {
 | 
				
			||||||
		verify(connection).close();
 | 
							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
 | 
						@Test
 | 
				
			||||||
	public void testQueryWithRowCallbackHandlerNoParameters() throws SQLException {
 | 
						public void testQueryWithRowCallbackHandlerNoParameters() throws SQLException {
 | 
				
			||||||
		given(resultSet.next()).willReturn(true, false);
 | 
							given(resultSet.next()).willReturn(true, false);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue