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

3.5.2及3.5.3

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

自定义一个List转Varchar的TypeHandler后,新增修改没问题,调用updateById就报错。跟踪源码后发现 org.apache.ibatis.reflection.ParamNameResolver把实体类转成了”el->实体的map形式“,导致没找到对应的TypeHandler,最终添加 @TableField(typeHandler = MPConfig.MybatisListStringTypeHandler.class)能解决updateById报错问题。 诉求是能不能不加注解就完成类型转换。

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

/* * 自定义配置 / @Bean ConfigurationCustomizer defaultConfigurationCustomizer() { return configuration -> { configuration.getTypeHandlerRegistry().register(MybatisListStringTypeHandler.class); }; }

/**
 * List转字符串
 *
 * @author wuzzzh
 */
public static class MybatisListStringTypeHandler extends BaseTypeHandler<List<String>> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, CollUtil.join(parameter, ","));
    }

    @Override
    public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String result = rs.getString(columnName);
        if (StrUtil.isNotBlank(result)) {
            return ListUtil.of(result.split(","));
        }
        return null;
    }

    @Override
    public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String result = rs.getString(columnIndex);
        if (StrUtil.isNotBlank(result)) {
            return ListUtil.of(result.split(","));
        }
        return null;
    }

    @Override
    public List<String> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String result = cs.getString(columnIndex);
        if (StrUtil.isNotBlank(result)) {
            return ListUtil.of(result.split(","));
        }
        return null;
    }
}

/* * 菜单表 entity * / @Data public class SysMenu {

/**
 * 主键
 */
private Integer id;

/**
 * 菜单名称
 */
private String name;

/**
 * 菜单类型
 */
private SysMenuType type;

/**
 * 权限标识
 */
private String authority;

// @TableField(typeHandler = MPConfig.MybatisListStringTypeHandler.class) private List test1; }

报错信息

org.springframework.jdbc.UncategorizedSQLException:

Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'test1' at row 1

The error may exist in com/zimo/admin/mapper/SysMenuMapper.java (best guess)

The error may involve com.zimo.admin.mapper.SysMenuMapper.updateById-Inline

The error occurred while setting parameters

SQL: UPDATE sys_menu SET type=?, test1=? WHERE id=?

Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'test1' at row 1

Comment From: miemieYaho

要么加入到mybatis全局typehandler,要么加注解,你这种大范围的typehandler如果加入全局是会出现很多bug的

Comment From: YuCyan

我遇到的问题恰恰和你相反,我用的是模型+注解@TableField(typeHandler = "xxxxx") , 然后使用LambdaUpdateWrapper进行目标字段做局部更新,此时目标字段上面注解的typehandler信息失效:

实体属性: /* * 类型映射-varchar / @TableField(value = "varchar", typeHandler = JacksonTypeHandler.class) private List varchar;

更新方式: update(new LambdaUpdateWrapper<>(ListTypeModel.class) .eq(ListTypeModel::getId, id) .set(ListTypeModel::getVarchar, points) ); 异常信息:

Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1

The error may exist in com/lambda/cloud/example/mybatisplus/domain/mapper/ListTypeModelMapper.java (best guess)

The error may involve com.lambda.cloud.example.mybatisplus.domain.mapper.ListTypeModelMapper.updateVarchar-Inline

The error occurred while setting parameters

SQL: update t_type_handler_list set varchar = ? where id = ?

Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1

; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1] with root cause

最终采用updateById(E entity)的方式规避了问题,但是并没有解决问题

诉求可以直接使用LambdaUpdateWrapper直接对注解有typehandler的字段进行局部更新

Comment From: ryanorz

我遇到的问题恰恰和你相反,我用的是模型+注解@TableField(typeHandler = "xxxxx") , 然后使用LambdaUpdateWrapper进行目标字段做局部更新,此时目标字段上面注解的typehandler信息失效:

实体属性: /**

  • 类型映射-varchar */ @TableField(value = "varchar", typeHandler = JacksonTypeHandler.class) private List varchar;

更新方式: update(new LambdaUpdateWrapper<>(ListTypeModel.class) .eq(ListTypeModel::getId, id) .set(ListTypeModel::getVarchar, points) ); 异常信息:

Error updating database. Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1

The error may exist in com/lambda/cloud/example/mybatisplus/domain/mapper/ListTypeModelMapper.java (best guess)

The error may involve com.lambda.cloud.example.mybatisplus.domain.mapper.ListTypeModelMapper.updateVarchar-Inline

The error occurred while setting parameters

SQL: update t_type_handler_list set varchar = ? where id = ?

Cause: java.sql.SQLException: Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1

; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: '\xAC\xED\x00\x05sr...' for column 'varchar' at row 1] with root cause

最终采用updateById(E entity)的方式规避了问题,但是并没有解决问题

诉求可以直接使用LambdaUpdateWrapper直接对注解有typehandler的字段进行局部更新

遇到了一样的问题,可以通过手动序列化解决,例如 update(new LambdaUpdateWrapper<>(ListTypeModel.class) .eq(ListTypeModel::getId, id) .set(ListTypeModel::getVarchar, JSON.toJSONString(points)) );

Comment From: x2zh

请问为什么关闭了?是已经修复了吗?

Comment From: cnbeiyu

3.5.16还是有这个问题