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
相关产品推荐
相关产品推荐

