当前使用版本(必填,否则不予处理)
3.5.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;
}
重现步骤(如果有就写完整)
- 按我的理解,当前注册的类型是JsonNode类型用JacksonTypeHandler 处理;我除了默认的JsonNode类型可以用JacksonTypeHandler 处理,其他类型也可以用JacksonTypeHandler转json处理。
- 实际情况是
- 如果我不向mybatis注册全局的JacksonTypeHandler, 任何类型都可以用@TableField(typeHandler = JacksonTypeHandler.class)转json;
- 如果我向mybatis注册了全局的JacksonTypeHandler,使用@TableField(typeHandler = JacksonTypeHandler.class) 转json 会报非法参数错误
- 个人跟踪代码:
- com.baomidou.mybatisplus.core.metadata.TableFieldInfo#getResultMapping 会先从mybatis 全局注册缓存里面拿,拿到之后直接就使用(这时候全局解析的是JsonNode 类型,但是实际类型可能是其他类型); 拿不到会调用mybatis 的反射创建对应的handler 然后使用。
- 修复建议:(拿的时候根据当前字段的实际类型去拿,这样比较精准, 拿不到就创建,这样避免类型不匹配) 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
赞