mybatis-plus icon indicating copy to clipboard operation
mybatis-plus copied to clipboard

update只有一个Collection类型的参数时(参数名为list)报错

Open kyle18th opened this issue 2 years ago • 2 comments

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

3.5.1

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

update时,只有一个Collection类型参数,参数名为list,不加@Param注解

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

void updateBatch(Collection<User> list); 参数list的值通过map.values()获取

原因分析:

Collection类型参数不加@Param注解且参数个数为1个时,最终会调用ParamNameResolver.wrapToMapIfCollection方法,生成一个ParamMap,含有2个key,分别为collectionlist

if (object instanceof Collection) {
  ParamMap<Object> map = new ParamMap<>();
  map.put("collection", object);
  if (object instanceof List) {
    map.put("list", object);
  }
  // actualParamName为参数的名字,报错场景时参数名为list
  Optional.ofNullable(actualParamName).ifPresent(name -> map.put(name, object));
  return map;
} 

然后com.baomidou.mybatisplus.core.MybatisParameterHandler进行处理时就会报错了

protected Collection<Object> getParameters(Object parameterObject) {
    Collection<Object> parameters = null;
    if (parameterObject instanceof Collection) {
        parameters = (Collection) parameterObject;
    } else if (parameterObject instanceof Map) {
        Map parameterMap = (Map) parameterObject;
        if (parameterMap.containsKey("collection")) {
            parameters = (Collection) parameterMap.get("collection");
        } if (parameterMap.containsKey(Constants.COLLECTION)) {
            // 兼容逻辑删除对象填充
            parameters = (Collection) parameterMap.get(Constants.COLLECTION);
        } else if (parameterMap.containsKey("list")) {
            parameters = (List) parameterMap.get("list");
        } else if (parameterMap.containsKey("array")) {
            parameters = Arrays.asList((Object[]) parameterMap.get("array"));
        }
    }
    return parameters;
}

parameterMap包含了collectionlist2个key,最后会走到parameterMap.containsKey("list")判断里,强转list报错,比较疑问的是为什么parameterMap.containsKey(Constants.COLLECTION)用了if而不是继续else if

报错信息

### Cause: java.lang.ClassCastException: java.util.HashMap$Values cannot be cast to java.util.List] with root cause java.lang.ClassCastException: java.util.HashMap$Values cannot be cast to java.util.List
	at com.baomidou.mybatisplus.core.MybatisParameterHandler.getParameters(MybatisParameterHandler.java:197)
	at com.baomidou.mybatisplus.core.MybatisParameterHandler.processParameter(MybatisParameterHandler.java:78)
	at com.baomidou.mybatisplus.core.MybatisParameterHandler.<init>(MybatisParameterHandler.java:67)
	at com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver.createParameterHandler(MybatisXMLLanguageDriver.java:45)
	at org.apache.ibatis.session.Configuration.newParameterHandler(Configuration.java:668)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:69)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:41)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:681)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:106)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
	at com.sun.proxy.$Proxy281.update(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
	at com.sun.proxy.$Proxy173.update(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:288)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:64)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy174.updateBatch(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy175.updateBatch(Unknown Source)

kyle18th avatar May 06 '22 09:05 kyle18th

你是自己写的updateBatch,通过自定义xml文件来完成批量保存。还是调用框架Service层的代码

jojocodeX avatar May 07 '22 00:05 jojocodeX

你是自己写的updateBatch,通过自定义xml文件来完成批量保存。还是调用框架Service层的代码

自定义的,这是之前的代码,之前没引入plus。

kyle18th avatar May 07 '22 00:05 kyle18th

你试下新版本已经换成 else if 如果还是不行打开 issue

qmdx avatar Dec 16 '22 01:12 qmdx