当前使用版本(必填,否则不予处理)
3.5.1
该问题是如何引起的?(确定最新版也有问题再提!!!)
低版本 实体类主键指明IdType.AUTO数据库自增,如果主键有值会忽略这个值;
https://github.com/baomidou/mybatis-plus/blob/87258ab7e7cf670922e61a82bee898a28f7a1ef9/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/metadata/TableInfo.java#L248
我们的代码有很多地方有 实体copy,主键id 可能会被赋值,以往都能正常插入。升级后插入报错。因为项目比较大,可能会改漏了。
希望能添加一个配置项,开启配置的时候,哪怕主键有值也直接忽略了,兼容老版本。
重现步骤(如果有就写完整)
实体类主键指明IdType.AUTO数据库自增 ,然后赋值,调用Insert
报错信息
重复主键异常
Comment From: chen8238065
@Service public class AutoInsertInnerInterceptor implements InnerInterceptor {
@Override
public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
if (ms.getSqlCommandType() == SqlCommandType.INSERT) {
ReflectionUtils.doWithFields(parameter.getClass(),(field)->{
TableId annotation = field.getAnnotation(TableId.class);
if (annotation.type() == IdType.AUTO) {
field.setAccessible(true);
field.set(parameter,null);
}
},field -> field.isAnnotationPresent(TableId.class));
}
}
} 我先 临时方案 自己加拦截器强制转 null 了
Comment From: qmdx
你可以修改下实体 copy 的方法排除 id 避免重复对象引用这个问题,或者修改下插入注入 insert 方法加上主键ID的判断,可能会被你的临时方案更优一点,因为存在另外一批用户是允许 AUTO 的时候设置 ID 因此这个地方后续不会调整,交给用户自己处理。
Comment From: chen8238065
- 单个接口都比较好处理,历史项目,很多地方都在insert,主要是怕漏改了,所以只能先全局兼容历史版本。而且是统一的业务框架,升级后很多项目都要去排查这个问题。本质上,个人还是觉得应该是尽可能的要向下兼容,SOLID吗。
- 历史版本需要insert 指定主键值,我们 已经 自定义了一个 insertWithPrimaryKeyIfExist 的 MappedStatement 。(使用起来稍微复杂点,每个mapper 都要集成一个 自定义Mapper)
- 有没有可能 加个 IdType.AUTO 和 IdType.INPUT 双重语义的 标记,这样我们默认可以继续用AUTO,新的就可以用 INPUT_OR_AUTO 了.
Comment From: nieqiurong
用3.5.6-SNAPSHOT版本,可以开启下面配置试试.
mybatis-plus:
global-config:
db-config:
insert-ignore-auto-increment-column: true