You need to enable JavaScript to run this app. MyBatis更新PostgreSQL记录时如何忽略GENERATED ALWAYS类型的id字段
优惠活动
大模型
产品
解决方案
定价
更多

MyBatis更新PostgreSQL记录时如何忽略GENERATED ALWAYS类型的id字段

问题修复方案

错误原因

ERROR: column "id" can only be updated to DEFAULT
Detail: Column "id" is an identity column defined as GENERATED ALWAYS.

你的PostgreSQL表的id列是GENERATED ALWAYS类型的自增标识列,该类型列禁止用户手动更新值,只能由数据库自动生成。你当前代码的问题是:给用于更新的Users实体设置了id值,MyBatis的updateByExampleSelective方法会把所有非空的实体字段都拼接到SQL的SET子句中,最终生成的SQL包含了更新id的逻辑,触发数据库报错。

修复方案

方案1:更新实体不设置id字段,id仅作为查询条件

构造用于更新的Users对象时,仅设置需要修改的appleIapProductId字段,id单独放到查询条件中即可:

// 仅设置待更新的字段
Users users = new Users();
users.setAppleIapProductId(productId);

// 构造查询条件
UsersExample example = new UsersExample();
UsersExample.Criteria criteria = example.createCriteria();
criteria.andIdEqualTo(payTransactionRecord.getUserId());

return userMapper.updateByExampleSelective(users,example);

方案2:给id字段配置禁止更新注解

如果你的项目是通过MyBatis Generator(MBG)或者MyBatis-Plus生成的实体,可以在id字段上添加updatable = false的配置,这样就算实体设置了id值,也不会被拼接到更新的SET子句中:

@Column(updatable = false)
private Long id;

方案3:直接使用自带的按主键更新方法

MBG默认生成了updateByPrimaryKeySelective方法,该方法会自动把主键作为WHERE条件,仅更新非主键的非空字段,无需手动构造Example,代码更简洁:

public int updateByPrimaryKey(Users user) {
    // 自动使用id作为查询条件,仅更新设置的非主键字段
    return userMapper.updateByPrimaryKeySelective(user);
}

内容的提问来源于stack exchange,提问作者Dolphin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 19:45:02