Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NamedParameterJdbcTemplate.batchUpdate does not individually apply the SQL type from each SqlParameterSource argument #26071

Closed
silviomo opened this issue Nov 11, 2020 · 2 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: regression A bug that is also a regression
Milestone

Comments

@silviomo
Copy link

silviomo commented Nov 11, 2020

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 11, 2020
@jhoeller jhoeller changed the title Broken NamedParameterJdbcTemplate.batchUpdate NamedParameterJdbcTemplate.batchUpdate does not individually apply the SQL type from each SqlParameterSource argument Nov 11, 2020
@jhoeller jhoeller self-assigned this Nov 11, 2020
@jhoeller jhoeller added this to the 5.3.2 milestone Nov 11, 2020
@jhoeller jhoeller added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Nov 11, 2020
@jhoeller
Copy link
Contributor

Thanks for raising this! Looks like a regression caused by #21935 (about two years ago). We used to derive named parameter replacement from the first batch arguments (which is still necessary), but since then we're also taking the SQL type indications from the first argument entry only. I guess most batches use the same types anyway, otherwise we'd have noticed earlier. In any case, this is easy enough to address through SqlParameterValue wrapping, hopefully also easy enough to backport.

@jhoeller jhoeller added type: regression A bug that is also a regression for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 11, 2020
@spring-projects-issues spring-projects-issues added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x labels Nov 11, 2020
@jhoeller jhoeller added the for: backport-to-5.1.x Marks an issue as a candidate for backport to 5.1.x label Nov 11, 2020
@spring-projects-issues spring-projects-issues removed the for: backport-to-5.1.x Marks an issue as a candidate for backport to 5.1.x label Nov 11, 2020
@jhoeller
Copy link
Contributor

This is available in the latest snapshots now: 5.3.2, 5.2.12, 5.1.20 (see https://repo.spring.io/snapshot/org/springframework/spring-framework-bom/). It'd be great if you could give the fix an early try, we're going to release all of the above in early December.

It turned out that it was indeed a regression in 5.1.x. I've backported the test to 5.0.x and 4.3.x as well where it passes right away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

3 participants