当前使用版本(必填,否则不予处理)

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

  1. 单个接口都比较好处理,历史项目,很多地方都在insert,主要是怕漏改了,所以只能先全局兼容历史版本。而且是统一的业务框架,升级后很多项目都要去排查这个问题。本质上,个人还是觉得应该是尽可能的要向下兼容,SOLID吗。
  2. 历史版本需要insert 指定主键值,我们 已经 自定义了一个 insertWithPrimaryKeyIfExist 的 MappedStatement 。(使用起来稍微复杂点,每个mapper 都要集成一个 自定义Mapper)
  3. 有没有可能 加个 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