Caused by: org.apache.ibatis.reflection.ReflectionException: Could not set property ‘id‘ of ‘class

问题描述

Caused by: org.apache.ibatis.reflection.ReflectionException: Could not set property ‘id’ of ‘class XXX’ with value ‘XXX’ Cause: java.lang.IllegalArgumentException: argument type mismatch

这是mybatis保存数据时报的一个错,跟着源码找了一下原因。如下:

因为mybatis的全局配置com.baomidou.mybatisplus.core.config.GlobalConfig.DbConfig中,主键类型默认是ID_WORKER。

public static class DbConfig {
    /**
         * 主键类型(默认 ID_WORKER)
         */
    private IdType idType = IdType.ID_WORKER;

在表对应的实体类加载时,主键初始化流程中com.baomidou.mybatisplus.core.metadata.TableInfoHelper#initTableIdWithoutAnnotation,如果数据库表对应的实体类中有个字段名为id,会被默认当做存在的主键,并且设置主键自动生成器为全局配置的IdType.

/**
     * 默认表主键名称
     */
private static final String DEFAULT_ID_NAME = "id";
/**
     * 

* 主键属性初始化 *

* * @param tableInfo 表信息 * @param field 字段 * @param clazz 实体类 * @return true 继续下一个属性判断,返回 continue; */
private static boolean initTableIdWithoutAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo, Field field, Class<?> clazz) { // 省略...... if (DEFAULT_ID_NAME.equalsIgnoreCase(column)) { if (StringUtils.isEmpty(tableInfo.getKeyColumn())) { tableInfo.setKeyRelated(checkRelated(tableInfo.isUnderCamel(), field.getName(), column)) .setIdType(dbConfig.getIdType()) .setKeyColumn(column) .setKeyProperty(field.getName()) .setKeyType(field.getType()); return true; } else { throwExceptionId(clazz); } } return false; }

在调用insert类型的方法时,如果主键为空,会根据IdType的类型来填充主键,生成主键的方法是IdWorker.getId()

/**
     * 自定义元对象填充控制器
     *
     * @param metaObjectHandler 元数据填充处理器
     * @param tableInfo         数据库表反射信息
     * @param ms                MappedStatement
     * @param parameterObject   插入数据库对象
     * @return Object
     */
protected static Object populateKeys(MetaObjectHandler metaObjectHandler, TableInfo tableInfo,
                                     MappedStatement ms, Object parameterObject, boolean isInsert) {
    // 省略......
    // 填充主键
    if (isInsert && !StringUtils.isEmpty(tableInfo.getKeyProperty())
        && null != tableInfo.getIdType() && tableInfo.getIdType().getKey() >= 3) {
        Object idValue = metaObject.getValue(tableInfo.getKeyProperty());
        /* 自定义 ID */
        if (StringUtils.checkValNull(idValue)) {
            if (tableInfo.getIdType() == IdType.ID_WORKER) {
                metaObject.setValue(tableInfo.getKeyProperty(), IdWorker.getId());
            } else if (tableInfo.getIdType() == IdType.ID_WORKER_STR) {
                metaObject.setValue(tableInfo.getKeyProperty(), IdWorker.getIdStr());
            } else if (tableInfo.getIdType() == IdType.UUID) {
                metaObject.setValue(tableInfo.getKeyProperty(), IdWorker.get32UUID());
            }
        }
    }
    // 省略......
}

IdWorker.getId()方法是通过时间戳生成的一个lang类型的随机数,此时如果我们的id类型是Integer,就会报错argument type mismatch了。

你可能感兴趣的:(mybatis)