mybatis-plus 包引用踩坑
开发过程经常使用mybatis-plus插件对mybatis进行增强操作,它对mybatis的一般操作做了一层封装,使用起来简单快捷
但是,往往也隐藏着风险。今天就有一个问题,导致自己查找了好久,最后发现是引用包的问题导致。。。
问题现象:
保存操作,执行成功数据库返回data为插入数据返回id,但是这个id一看就是未指定自增情况先导致的。
首先,排查数据库,数据库表主键是否设置自增:
数据库没有勾上自增,勾上,执行命令truncate table xxxx;
再查看entity定义:
mybatis-plus生成代码未指定type,加上type=IdType.AUTO
再次执行新增操作:
依然有问题
然后,就开启了漫长的探索之路:
跟踪源码 saveOrUpdate:
@Transactional( rollbackFor = {Exception.class} ) public boolean saveOrUpdate(T entity) { if (null == entity) { return false; } else { Class<?> cls = entity.getClass(); TableInfo tableInfo = TableInfoHelper.getTableInfo(cls); Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]); String keyProperty = tableInfo.getKeyProperty(); Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]); Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty()); return !StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal)) ? this.updateById(entity) : this.save(entity); } }
打断点第9行,发现这个tableInfo中的idType类型是ASSIGN_ID
这放谁受得了,直接跟进getTableInfo去看看,为啥会是这个样子。
public static TableInfo getTableInfo(Class<?> clazz) { if (clazz != null && !ReflectionKit.isPrimitiveOrWrapper(clazz) && clazz != String.class) { TableInfo tableInfo = (TableInfo)TABLE_INFO_CACHE.get(ClassUtils.getUserClass(clazz)); if (null != tableInfo) { return tableInfo; } else { for(Class currentClass = clazz; null == tableInfo && Object.class != currentClass; tableInfo = (TableInfo)TABLE_INFO_CACHE.get(ClassUtils.getUserClass(currentClass))) { currentClass = currentClass.getSuperclass(); } if (tableInfo != null) { TABLE_INFO_CACHE.put(ClassUtils.getUserClass(clazz), tableInfo); } return tableInfo; } } else { return null; } }
发现这个玩意儿是个缓存,然后重新编译重启应用--不行 ---> 删表--建表--不行;来来回回搞了几次。扛不住了,搞崩溃了,唯一的成就就是排除了数据库的嫌疑,那么问题肯定出现在代码层面。然后,蓦然回首,发现之前多次试验发现那个idType一直稳如老狗,不论我怎么改,它一直是ASSIGN_ID。我赶紧去看了下IdType的源码,如下:
我去,这个里面没这个ASSIGN_ID类型!!!
那么,问题来了,我运行时加载的这个类型从哪儿来的呢,它毫无疑问,肯定是个默认值,难道是我引用包的问题?
赶紧滚去看下正常的entity里面引用的IdType包的,是下图这个样子的:
对比下自己的
哦豁!!!终于找到问题原因了。看下这个annotations包下面的IdType:
里面有那个万恶的ASSIGN_ID了
修改引用包类型,重启应用(别忘了数据库执行truncate table xxxx),新增数据:
bingo,好了!!!
延伸:
1、这次问题查找,如果没有参考的那么,这个问题突破点还是在那个IdType这个类型上,应该点进去看下这个IdType在源码中用的是哪个包下的:
看着没,这里已经很明显的发现问题了。
2、我在其他工程也发现其他的使用方式,如下图所示:
这个与我使用的方式是怎么不一样的?都是苞米豆的,为啥会存在这两种方式?等着以后探索。。。