Individually apply the SQL type from each SqlParameterSource argument
Closes gh-26071
This commit is contained in:
parent
6eec1acdac
commit
66292cd7a1
|
|
@ -30,7 +30,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class that efficiently creates multiple {@link PreparedStatementCreator}
|
* Helper class that efficiently creates multiple {@link PreparedStatementCreator}
|
||||||
|
|
@ -200,9 +199,8 @@ public class PreparedStatementCreatorFactory {
|
||||||
|
|
||||||
public PreparedStatementCreatorImpl(String actualSql, List<?> parameters) {
|
public PreparedStatementCreatorImpl(String actualSql, List<?> parameters) {
|
||||||
this.actualSql = actualSql;
|
this.actualSql = actualSql;
|
||||||
Assert.notNull(parameters, "Parameters List must not be null");
|
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
if (this.parameters.size() != declaredParameters.size()) {
|
if (parameters.size() != declaredParameters.size()) {
|
||||||
// Account for named parameters being used multiple times
|
// Account for named parameters being used multiple times
|
||||||
Set<String> names = new HashSet<>();
|
Set<String> names = new HashSet<>();
|
||||||
for (int i = 0; i < parameters.size(); i++) {
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
|
|
|
||||||
|
|
@ -345,9 +345,9 @@ public abstract class NamedParameterUtils {
|
||||||
for (int i = 0; i < paramNames.size(); i++) {
|
for (int i = 0; i < paramNames.size(); i++) {
|
||||||
String paramName = paramNames.get(i);
|
String paramName = paramNames.get(i);
|
||||||
try {
|
try {
|
||||||
Object value = paramSource.getValue(paramName);
|
|
||||||
SqlParameter param = findParameter(declaredParams, paramName, i);
|
SqlParameter param = findParameter(declaredParams, paramName, i);
|
||||||
paramArray[i] = (param != null ? new SqlParameterValue(param, value) : value);
|
paramArray[i] = (param != null ? new SqlParameterValue(param, paramSource.getValue(paramName)) :
|
||||||
|
SqlParameterSourceUtils.getTypedValue(paramSource, paramName));
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException ex) {
|
catch (IllegalArgumentException ex) {
|
||||||
throw new InvalidDataAccessApiUsageException(
|
throw new InvalidDataAccessApiUsageException(
|
||||||
|
|
|
||||||
|
|
@ -92,18 +92,14 @@ public abstract class SqlParameterSourceUtils {
|
||||||
* @param source the source of parameter values and type information
|
* @param source the source of parameter values and type information
|
||||||
* @param parameterName the name of the parameter
|
* @param parameterName the name of the parameter
|
||||||
* @return the value object
|
* @return the value object
|
||||||
|
* @see SqlParameterValue
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Object getTypedValue(SqlParameterSource source, String parameterName) {
|
public static Object getTypedValue(SqlParameterSource source, String parameterName) {
|
||||||
int sqlType = source.getSqlType(parameterName);
|
int sqlType = source.getSqlType(parameterName);
|
||||||
if (sqlType != SqlParameterSource.TYPE_UNKNOWN) {
|
if (sqlType != SqlParameterSource.TYPE_UNKNOWN) {
|
||||||
if (source.getTypeName(parameterName) != null) {
|
|
||||||
return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
|
return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return new SqlParameterValue(sqlType, source.getValue(parameterName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return source.getValue(parameterName);
|
return source.getValue(parameterName);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -561,10 +561,11 @@ public class NamedParameterJdbcTemplateTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchUpdateWithSqlParameterSourcePlusTypeInfo() throws Exception {
|
public void testBatchUpdateWithSqlParameterSourcePlusTypeInfo() throws Exception {
|
||||||
SqlParameterSource[] ids = new SqlParameterSource[2];
|
SqlParameterSource[] ids = new SqlParameterSource[3];
|
||||||
ids[0] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC);
|
ids[0] = new MapSqlParameterSource().addValue("id", null, Types.NULL);
|
||||||
ids[1] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC);
|
ids[1] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC);
|
||||||
final int[] rowsAffected = new int[] {1, 2};
|
ids[2] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC);
|
||||||
|
final int[] rowsAffected = new int[] {1, 2, 3};
|
||||||
|
|
||||||
given(preparedStatement.executeBatch()).willReturn(rowsAffected);
|
given(preparedStatement.executeBatch()).willReturn(rowsAffected);
|
||||||
given(connection.getMetaData()).willReturn(databaseMetaData);
|
given(connection.getMetaData()).willReturn(databaseMetaData);
|
||||||
|
|
@ -572,13 +573,15 @@ public class NamedParameterJdbcTemplateTests {
|
||||||
|
|
||||||
int[] actualRowsAffected = namedParameterTemplate.batchUpdate(
|
int[] actualRowsAffected = namedParameterTemplate.batchUpdate(
|
||||||
"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id", ids);
|
"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id", ids);
|
||||||
assertThat(actualRowsAffected.length == 2).as("executed 2 updates").isTrue();
|
assertThat(actualRowsAffected.length == 3).as("executed 3 updates").isTrue();
|
||||||
assertThat(actualRowsAffected[0]).isEqualTo(rowsAffected[0]);
|
assertThat(actualRowsAffected[0]).isEqualTo(rowsAffected[0]);
|
||||||
assertThat(actualRowsAffected[1]).isEqualTo(rowsAffected[1]);
|
assertThat(actualRowsAffected[1]).isEqualTo(rowsAffected[1]);
|
||||||
|
assertThat(actualRowsAffected[2]).isEqualTo(rowsAffected[2]);
|
||||||
verify(connection).prepareStatement("UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?");
|
verify(connection).prepareStatement("UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?");
|
||||||
|
verify(preparedStatement).setNull(1, Types.NULL);
|
||||||
verify(preparedStatement).setObject(1, 100, Types.NUMERIC);
|
verify(preparedStatement).setObject(1, 100, Types.NUMERIC);
|
||||||
verify(preparedStatement).setObject(1, 200, Types.NUMERIC);
|
verify(preparedStatement).setObject(1, 200, Types.NUMERIC);
|
||||||
verify(preparedStatement, times(2)).addBatch();
|
verify(preparedStatement, times(3)).addBatch();
|
||||||
verify(preparedStatement, atLeastOnce()).close();
|
verify(preparedStatement, atLeastOnce()).close();
|
||||||
verify(connection, atLeastOnce()).close();
|
verify(connection, atLeastOnce()).close();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue