当前使用版本(必填,否则不予处理)

3.5.1

该问题是如何引起的?(确定最新版也有问题再提!!!)

  1. 向mybatis注册一个全局TypeHandler
@Component
public class MybatisCustomTypeHandler implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
        TypeHandlerRegistry typeHandlerRegistry = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
        typeHandlerRegistry.register(JsonNode.class, JacksonTypeHandler.class);
    }
}

(2) 上面代码对于JSON类型的字段没错误信息,对于其他类型会报错。 如下代码解析会报错:

    @TableField(typeHandler = JacksonTypeHandler.class)
    private ElementStyle elementStyle;

    @Data
    public static class ElementStyle implements Serializable {
        private List<String> list;
        private List<Object> objList;
        private String name;
    }

重现步骤(如果有就写完整)

  1. 按我的理解,当前注册的类型是JsonNode类型用JacksonTypeHandler 处理;我除了默认的JsonNode类型可以用JacksonTypeHandler 处理,其他类型也可以用JacksonTypeHandler转json处理。
  2. 实际情况是
  3. 如果我不向mybatis注册全局的JacksonTypeHandler, 任何类型都可以用@TableField(typeHandler = JacksonTypeHandler.class)转json;
  4. 如果我向mybatis注册了全局的JacksonTypeHandler,使用@TableField(typeHandler = JacksonTypeHandler.class) 转json 会报非法参数错误
  5. 个人跟踪代码:
  6. com.baomidou.mybatisplus.core.metadata.TableFieldInfo#getResultMapping 会先从mybatis 全局注册缓存里面拿,拿到之后直接就使用(这时候全局解析的是JsonNode 类型,但是实际类型可能是其他类型); 拿不到会调用mybatis 的反射创建对应的handler 然后使用。
  7. 修复建议:(拿的时候根据当前字段的实际类型去拿,这样比较精准, 拿不到就创建,这样避免类型不匹配) TypeHandler<?> typeHandler = registry.getMappingTypeHandler(this.typeHandler); 改为用当前需要处理的类的class 去拿, 如下: ```java typeHandlerRegistry.getTypeHandler(propertyType); // 拿需要获取的类型去获取

### 报错信息
```java
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'elementStyle' of 'class com.qax.aflab.setting.po.GraphModelElementTypePO' with value '{"list":["xiexie"],"name":"dundun","objList":[{"age":5}]}' Cause: java.lang.IllegalArgumentException: argument type mismatch

    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
    at com.sun.proxy.$Proxy136.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
    at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166)
    at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77)
    at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)

Comment From: miemieYaho

BaseBuilder.resolveTypeHandler 就是这么处理的,就是说如果你只用mybatis,并且全局一个JacksonTypeHandler并且在xml里的resultmap指定字段JacksonTypeHandler,依然是一样的结果

Comment From: VampireAchao