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";
/**
     * <p>
     * 主键属性初始化
     * </p>
     *
     * @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了。

猜你喜欢

转载自blog.csdn.net/u013041642/article/details/107416692