Description
The class NamedParameterJdbcTemplate has following method:
@Nonnull
@Override
public int[] batchUpdate(@Nonnull String sql, @Nonnull SqlParameterSource[] batchArgs) {
// implementation
}
The method signature suggests fine-grained control over the SQL type hints, so that these could be customised for each element in the array, however, this is not true.
As a matter of fact, only the SQL hints for the first element in the array are processed, they are then applied to all the elements in the batch by PreparedStatementCreatorFactory.
This can lead to exceptions within the JDBC driver, for example when using MySQL/MariaDB. Consider the following table definition and inserts:
CREATE TABLE `names` (
`first_name` VARCHAR(30) NOT NULL,
`nick_name` VARCHAR(30) NULL
);
INSERT INTO `names`(`first_name`, `nick_name`) VALUES(:first_name, :nick_name);
Now consider this Java:
MapSqlParameterSource sqlParameterSource1 = new MapSqlParameterSource();
sqlParameterSource2.addValue("first_name", "Jose", Types.VARCHAR);
sqlParameterSource2.addValue("nick_name", null, Types.NULL);
MapSqlParameterSource sqlParameterSource2 = new MapSqlParameterSource();
sqlParameterSource1.addValue("first_name", "Silvio", Types.VARCHAR);
sqlParameterSource1.addValue("nick_name", "Silv", Types.VARCHAR);
SqlParameterSource[] batch = new SqlParameterSource[] {
sqlParameterSource1,
sqlParameterSource2
};
namedParameterJdbcTemplate.batchUpdate(sql, batch);
This will throw an exception in the MySQL driver because Types.NULL from the first element will be applied to the second element as well.
Cannot convert class java.lang.String to SQL type requested due to com.mysql.cj.exceptions.WrongArgumentException - Conversion from java.lang.String to NULL is not supported.