Closed
Description
MyBatis version
3.5.1
Database vendor and version
PostgreSQL 11.+
Test case or example project
@Test
void shouldAutoRegisterEnumTypeInMultiThreadEnvironment() {
for (int iteration = 0; iteration < 1000; iteration++) {
TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
CountDownLatch startLatch = new CountDownLatch(1);
List<Future<Object>> taskResults = IntStream.range(0, THREAD_COUNT)
.mapToObj(taskIndex -> executorService.submit(() -> {
startLatch.await();
assertTrue(typeHandlerRegistry.hasTypeHandler(TestEnum.class, JdbcType.VARCHAR),
"TypeHandler not registered");
return null;
})).collect(Collectors.toList());
startLatch.countDown();
taskResults.forEach(Futures::getUnchecked);
}
}
Steps to reproduce
Expected result
typeHandlerRegistry.hasTypeHandler(TestEnum.class, JdbcType.VARCHAR) always true
Actual result
sometimes i got result false. If it happened i get strange exceptions with read/write enum values:
Caused by: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='role', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: ...SqlException: database: [xxx]; connection: [/127.0.0.1:xxx -> localhost/127.0.0.1:xxx]; state: [07006]; reason: [Can't infer the SQL type to use for an instance of xxx.Role. Use setObject() with an explicit Types value to specify the type to use.]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy72.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)
at com.sun.proxy.$Proxy115.addUserToAccount(Unknown Source)
... 27 more
Caused by: org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='role', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: ...SqlException: database: [xxx]; connection: [/127.0.0.1:xxx -> localhost/127.0.0.1:xxx]; state: [07006]; reason: [Can't infer the SQL type to use for an instance of xxx.Role. Use setObject() with an explicit Types value to specify the type to use.]
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:89)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:94)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:64)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:87)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184)
at jdk.internal.reflect.GeneratedMethodAccessor240.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 34 more
Caused by: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: ...SqlException: database: [xxx]; connection: [/127.0.0.1:xxx -> localhost/127.0.0.1:xxx]; state: [07006]; reason: [Can't infer the SQL type to use for an instance of xxx.Role. Use setObject() with an explicit Types value to specify the type to use.]
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:71)
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87)
... 46 more
Caused by: org.apache.ibatis.type.TypeException: Error setting non null for parameter #6 with JdbcType null . Try setting a different JdbcType for this parameter or a different configuration property. Cause: ...SqlException: database: [xxx]; connection: [/127.0.0.1:xxx -> localhost/127.0.0.1:xxx]; state: [07006]; reason: [Can't infer the SQL type to use for an instance of xxx.Role. Use setObject() with an explicit Types value to specify the type to use.]
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:71)
at org.apache.ibatis.type.UnknownTypeHandler.setNonNullParameter(UnknownTypeHandler.java:45)
at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:69)
... 47 more
or
Caused by: java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createUsingConstructor(DefaultResultSetHandler.java:669)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:654)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:618)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:591)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:397)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
... 36 more