Skip to content

Commit 2d7e473

Browse files
artembilangaryrussell
authored andcommitted
GH-3243: sync computeIfAbsent in StoredProcExec
Fixes #3243 It turns out that `ConcurrentModificationException` is thrown from the `HashMap.computeIfAbsent(HashMap.java:1134)` since Java 9 when the map is modified concurrently independently from the key we try to modify * Check for the value presence before computing * `synchronized(this.jdbcCallOperationsMap)` around `computeIfAbsent()` when `get() == null` **Cherry-pick to 5.2.x**
1 parent cd64a09 commit 2d7e473

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/StoredProcExecutor.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ public class StoredProcExecutor implements BeanFactoryAware, InitializingBean {
6262

6363
private final DataSource dataSource;
6464

65+
private final Object jdbcCallOperationsMapMonitor = new Object();
66+
6567
private Map<String, RowMapper<?>> returningResultSetRowMappers = new HashMap<>(0);
6668

6769
private EvaluationContext evaluationContext;
@@ -296,7 +298,14 @@ private Map<String, Object> executeStoredProcedureInternal(Object input, String
296298
}
297299

298300
private SimpleJdbcCallOperations obtainSimpleJdbcCall(String storedProcedureName) {
299-
return this.jdbcCallOperationsMap.computeIfAbsent(storedProcedureName, this::createSimpleJdbcCall);
301+
SimpleJdbcCallOperations operations = this.jdbcCallOperationsMap.get(storedProcedureName);
302+
if (operations == null) {
303+
synchronized (this.jdbcCallOperationsMapMonitor) {
304+
operations =
305+
this.jdbcCallOperationsMap.computeIfAbsent(storedProcedureName, this::createSimpleJdbcCall);
306+
}
307+
}
308+
return operations;
300309
}
301310

302311
//~~~~~Setters for Properties~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)