Skip to content

Commit cad947f

Browse files
authored
Merge pull request #1820 from PVlyubinskiy/master
Prevent race condition in TypeHandlerRegistry
2 parents c1b26f8 + beeb15f commit cad947f

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2019 the original author or authors.
2+
* Copyright 2009-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -393,9 +393,9 @@ private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler)
393393
Map<JdbcType, TypeHandler<?>> map = typeHandlerMap.get(javaType);
394394
if (map == null || map == NULL_TYPE_HANDLER_MAP) {
395395
map = new HashMap<>();
396-
typeHandlerMap.put(javaType, map);
397396
}
398397
map.put(jdbcType, handler);
398+
typeHandlerMap.put(javaType, map);
399399
}
400400
allTypeHandlersMap.put(handler.getClass(), handler);
401401
}

src/test/java/org/apache/ibatis/type/TypeHandlerRegistryTest.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2019 the original author or authors.
2+
* Copyright 2009-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,6 +24,11 @@
2424
import java.sql.SQLException;
2525
import java.util.Date;
2626
import java.util.List;
27+
import java.util.concurrent.ExecutorService;
28+
import java.util.concurrent.Executors;
29+
import java.util.concurrent.Future;
30+
import java.util.stream.Collectors;
31+
import java.util.stream.IntStream;
2732

2833
import org.apache.ibatis.domain.misc.RichType;
2934
import org.junit.jupiter.api.BeforeEach;
@@ -215,4 +220,30 @@ class Address {
215220
typeHandlerRegistry.register(Address.class, StringTypeHandler.class);
216221
assertTrue(typeHandlerRegistry.hasTypeHandler(Address.class));
217222
}
223+
224+
enum TestEnum {
225+
ONE,
226+
TWO
227+
}
228+
229+
@Test
230+
void shouldAutoRegisterEnutmTypeInMultiThreadEnvironment() throws Exception {
231+
// gh-1820
232+
ExecutorService executorService = Executors.newCachedThreadPool();
233+
try {
234+
for (int iteration = 0; iteration < 2000; iteration++) {
235+
TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
236+
List<Future<Boolean>> taskResults = IntStream.range(0, 2)
237+
.mapToObj(taskIndex -> executorService.submit(() -> {
238+
return typeHandlerRegistry.hasTypeHandler(TestEnum.class, JdbcType.VARCHAR);
239+
})).collect(Collectors.toList());
240+
for (int i = 0; i < taskResults.size(); i++) {
241+
Future<Boolean> future = taskResults.get(i);
242+
assertTrue(future.get(), "false is returned at round " + iteration);
243+
}
244+
}
245+
} finally {
246+
executorService.shutdownNow();
247+
}
248+
}
218249
}

0 commit comments

Comments
 (0)