项目中用到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中的一个唯一性值为主键