使用Golang GORM插入数据后无法获取正确的插入记录主键ID
问题原因
- 主键字段冲突:你定义的
User结构体同时自定义了Id字段,又嵌入了gorm.Model。gorm.Model原生包含ID uint、CreatedAt、UpdatedAt、DeletedAt四个字段,GORM默认会优先将嵌入结构体的ID字段识别为表主键,你自定义的Id字段不会被当作主键处理。插入成功后GORM只会给嵌入的ID字段赋值,你读取自定义的Id自然得到初始值0。 - 标签优先级冲突:你虽然给自定义
Id加了primaryKey标签,但gorm.Model自带的ID字段也配置了主键标签,同结构体存在多个主键标识时你没有显式指定优先级,导致自定义的主键配置未生效。 - 额外排查点:如果排除字段冲突问题,需要检查
Create操作是否执行成功,未捕获的插入错误也会导致主键字段未被赋值。
解决方案
方案1:直接使用gorm.Model自带的ID字段(官方推荐)
删除你自定义的Id字段,插入后直接读取gorm.Model自带的ID即可:
type User struct { Name string `json:"name"` gorm.Model }
插入逻辑示例:
user := User{} user.Name = "Afzal" // 建议添加错误判断,确认插入成功 if err := DB.Create(&user).Error; err != nil { // 处理插入错误 } // user.ID即为新插入记录的主键值
方案2:保留自定义Id,移除gorm.Model嵌入
如果你希望用自定义的Id作为主键,且自己控制结构体字段,可以移除gorm.Model嵌入,需要软删、时间字段时单独定义即可:
import "gorm.io/gorm" type User struct { Id int `json:"id" gorm:"primaryKey;autoIncrement"` Name string `json:"name"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` }
插入后读取user.Id即可获得正确的主键值。
方案3:同时保留自定义Id和gorm.Model(不推荐)
如果业务必须同时保留两个字段,可以显式给嵌入的gorm.Model添加前缀或者忽略ID字段,避免主键冲突:
type User struct { Id int `json:"id" gorm:"primaryKey;autoIncrement"` Name string `json:"name"` // 给嵌入的Model字段添加前缀避免冲突 gorm.Model `gorm:"embedded;embeddedPrefix:model_"` }
内容的提问来源于stack exchange,提问作者Afzal Khan
相关产品推荐
相关产品推荐

