mybatisplus无主键表insert出现Class must not null报错

项目中用到pgsql+mybatisplus

insert数据报错

在调试过程中发现:

走到审计代码

entityClass为null,
entityClass是取自tableInfo的值

找到设置tableInfo的clazz字段的地方

com.baomidou.mybatisplus.core.toolkit.TableInfoHelper有一个initTableInfo方法

	public synchronized static TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class<?> clazz) {
		TableInfo tableInfo = TABLE_INFO_CACHE.get(clazz);
		if (tableInfo != null) {
			if (builderAssistant != null) {
				tableInfo.setConfigMark(builderAssistant.getConfiguration());
			}
			return tableInfo;
		}

		/* 没有获取到缓存信息,则初始化 */
		tableInfo = new TableInfo();
		GlobalConfig globalConfig;
		if (null != builderAssistant) {
			tableInfo.setCurrentNamespace(builderAssistant.getCurrentNamespace());
			tableInfo.setConfigMark(builderAssistant.getConfiguration());
			tableInfo.setUnderCamel(builderAssistant.getConfiguration().isMapUnderscoreToCamelCase());
			globalConfig = GlobalConfigUtils.getGlobalConfig(builderAssistant.getConfiguration());
		} else {
			// 兼容测试场景
			globalConfig = GlobalConfigUtils.defaults();
		}

		/* 初始化表名相关 */
		initTableName(clazz, globalConfig, tableInfo);

		/* 初始化字段相关 */
		initTableFields(clazz, globalConfig, tableInfo);

		/* 放入缓存 */
		TABLE_INFO_CACHE.put(clazz, tableInfo);

		/* 缓存 Lambda 映射关系 */
		LambdaUtils.createCache(clazz, tableInfo);
		return tableInfo;
	}

在初始化字段的时候,会通过是否有主键,如果有主键,会设置tableInfo的一些属性,而其中一个属性就是clazz,但是由于这张表没有设置主键,没有id字段,导致clazz属性为null

	/**
	 * <p>
	 * 初始化 表主键,表字段
	 * </p>
	 *
	 * @param clazz        实体类
	 * @param globalConfig 全局配置
	 * @param tableInfo    数据库表反射信息
	 */
	public static void initTableFields(Class<?> clazz, GlobalConfig globalConfig, TableInfo tableInfo) {
		/* 数据库全局配置 */
		GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
		List<Field> list = getAllFields(clazz);
		// 标记是否读取到主键
		boolean isReadPK = false;
		// 是否存在 @TableId 注解
		boolean existTableId = isExistTableId(list);
		boolean existId = isExistId(list);

		List<TableFieldInfo> fieldList = new ArrayList<>();
		for (Field field : list) {
			/*
			 * 主键ID 初始化
			 */
			if (!isReadPK) {
				if (existTableId) {
					isReadPK = initTableIdWithAnnotation(dbConfig, tableInfo, field, clazz);
				} else if (existId) {
					isReadPK = initIdWithAnnotation(dbConfig, tableInfo, field, clazz);
				} else {
					isReadPK = initTableIdWithoutAnnotation(dbConfig, tableInfo, field, clazz);
				}
				if (isReadPK) {
					continue;
				}
			}

			boolean existColumn = isExistColumn(field);


			/* 有 @TableField 注解的字段初始化 */
			if (initTableFieldWithAnnotation(dbConfig, tableInfo, fieldList, field, clazz)) {
				continue;
			}

			if (existColumn) {
                /* 获取注解属性,自定义字段 */
                Column column = field.getAnnotation(Column.class);
                String columnName = field.getName();
                if (StringUtils.isNotEmpty(column.name())) {
                    columnName = column.name();
                }
                initColumnFieldWithAnnotation(dbConfig, tableInfo, fieldList, field, clazz, columnName);
			} else {
                /* 无 @TableField/@Column 注解的字段初始化 */
			    initColumnFieldWithAnnotation(dbConfig, tableInfo, fieldList, field, clazz, field.getName());
            }

			/* 无 @TableField 注解的字段初始化 */
			//fieldList.add(new TableFieldInfo(dbConfig, tableInfo, field));
		}

		/* 检查逻辑删除字段只能有最多一个 */
		Assert.isTrue(fieldList.parallelStream().filter(TableFieldInfo::isLogicDelete).count() < 2L,
			String.format("annotation of @TableLogic can't more than one in class : %s.", clazz.getName()));

		/* 字段列表 */
		tableInfo.setFieldList(fieldList);

		/* 未发现主键注解,提示警告信息 */
		if (StringUtils.isEmpty(tableInfo.getKeyColumn())) {
			logger.warn(String.format("Warn: Could not find @TableId in Class: %s.", clazz.getName()));
		}
	}
	/**
	 * <p>
	 * 主键属性初始化
	 * </p>
	 *
	 * @param tableInfo 表信息
	 * @param field     字段
	 * @param clazz     实体类
	 * @return true 继续下一个属性判断,返回 continue;
	 */
	private static boolean initTableIdWithoutAnnotation(GlobalConfig.DbConfig dbConfig, TableInfo tableInfo,
		Field field, Class<?> clazz) {
		String column = field.getName();
		if (dbConfig.isCapitalMode()) {
			column = column.toUpperCase();
		}
		if (DEFAULT_ID_NAME.equalsIgnoreCase(column)) {//表中没有id字段,这里根本没执行
			if (StringUtils.isEmpty(tableInfo.getKeyColumn())) {
				tableInfo.setKeyRelated(checkRelated(tableInfo.isUnderCamel(), field.getName(), column))
					.setIdType(dbConfig.getIdType()).setKeyColumn(column).setKeyProperty(field.getName())
					.setClazz(field.getDeclaringClass());
				return true;
			} else {
				throwExceptionId(clazz);
			}
		}
		return false;
	}

解决办法:使用注解@TableId设置entity中的一个唯一性值为主键

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值