-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Closed as not planned
Closed as not planned
Copy link
Labels
in: dataIssues in data modules (jdbc, orm, oxm, tx)Issues in data modules (jdbc, orm, oxm, tx)status: invalidAn issue that we don't feel is validAn issue that we don't feel is valid
Description
I'm using the latest Spring boot 3.4.1.
How to reproduce bug:
- Create table in database:
@PostConstruct
public void createTable() {
final String sql = "CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name VARCHAR(255), company " +
"VARCHAR(255))";
jdbcTemplate.execute(sql);
}
- Use NamedParameterJdbcOperations for bulk update with this kinda query:
public void incorrectBulkUpdate(Map<String, List<String>> info) {
final String sql = "UPDATE users SET company = :company WHERE name IN (:names)";
SqlParameterSource[] params = info.entrySet().stream()
.sorted((e1, e2) -> Integer.compare(e1.getValue().size(), e2.getValue().size())) // pay attention to this line!!!
.map(e -> new MapSqlParameterSource()
.addValue("company", e.getKey())
.addValue("names", e.getValue())
)
.toArray(SqlParameterSource[]::new);
jdbcOperations.batchUpdate(sql, params);
}
In general I want to use bulk update with one of query arguments is a collection (in this example argument :names is a list).
Also I sorted parameters with increasing size order of :names argument.
3) Try to execute it with different sized :names argument, for example:
@Transactional
@Test
void incorrectBulkUpdateTest() {
simpleService.add("John", "google");
simpleService.add("Nick", "facebook");
simpleService.add("Anna", "netflix");
var found = simpleService.findByName("John");
assertEquals(1, found.size());
assertEquals("google", found.get(0).company);
simpleService.incorrectBulkUpdate(
Map.of(
"amazon", List.of("Nick", "Anna"),
"tesla", List.of("John")
)
);
found = simpleService.findByName("John");
assertEquals(1, found.size());
assertEquals("tesla", found.get(0).company);
}
And got something like:
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [UPDATE users SET company = ? WHERE name IN (?)]; The column index is out of range: 3, number of columns: 2.
But there is a twist.
If I sort arguments in decreasing order, like
.sorted((e1, e2) -> -Integer.compare(e1.getValue().size(), e2.getValue().size()))
everything is fine and test is successful.
I think there is some bug in SQL processing, when query with named parameters is transformed into a query with question marks.
You can see full example in repo: https://github.com/koalaa13/SpringBootIssueExample
Thank you in advance!
Alesiks and nkey0
Metadata
Metadata
Assignees
Labels
in: dataIssues in data modules (jdbc, orm, oxm, tx)Issues in data modules (jdbc, orm, oxm, tx)status: invalidAn issue that we don't feel is validAn issue that we don't feel is valid