I have two tables defined as follows
type BaseModel struct {
ID BigInt `gorm:"column:id;primaryKey;autoIncrement:false"`
CreatedAt int64 `gorm:"column:created_at;autoCreateTime:milli"`
}
func (b *BaseModel) BeforeCreate(tx *gorm.DB) (err error) {
b.ID = BigInt(GenerateSnowflakeID())
return
}
type User struct {
BaseModel
Password string `gorm:"column:password"`
Username string `gorm:"column:username;uniqueIndex"`
Token string `gorm:"column:token"`
Role enums.Role `gorm:"column:role"`
UpdatedAt int64 `gorm:"column:updated_at;autoCreateTime:milli;autoUpdateTime:milli"`
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;softDelete:milli;default:0"`
}
func (u *User) TableName() string {
return "users"
}
type Report struct {
BaseModel
UserID utils.BigInt `gorm:"column:user_id"`
User User `gorm:"foreignKey:UserID;references:ID"`
Title string `gorm:"column:title"`
Subtitle string `gorm:"column:subtitle"`
Content string `gorm:"longtext;column:content"`
UpdatedAt int64 `gorm:"column:updated_at;autoCreateTime:milli;autoUpdateTime:milli"`
DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;softDelete:milli;default:0"`
}
func (r *Report) TableName() string {
return "reports"
}
The steps I performed are as follows: 1. Use preload(User) + first to find the data of the specified id in the report table 2. Modify the title, subtitle, and content in the data and then update it
The pseudo code is as follows
record, err := gorm.G[entity.Report](r.getDB(ctx)).Where("id = ?", id).Preload("User", nil).First(ctx)
if err != nil {return err}
record.Title = title
record.Subtitle = subtitle
record.Content = content
err = r.getDB(ctx).Save(&record).Error
if err != nil {return err}
An error will be reported when saving: insert or update on table \"reports\" violates foreign key constraint \"fk_users_reports\" (SQLSTATE 23503)
The record content found above is as follows
#entity.Report {
+BaseModel => #utils.BaseModel {
+ID => 1967500364156506156
+CreatedAt => 1758000040268
}
+UserID => 1968216113971990528
+User => #entity.User {
+BaseModel => #utils.BaseModel {
+ID => 1968216113971990528
+CreatedAt => 1758094263915
}
+Password => "xxxx"
+Username => "Akkuman"
+Token => ""
+Role => admin #enums.Role
+UpdatedAt => 1758870514901
+DeletedAt => 0
}
+Title => "title"
+Subtitle => "subtitle"
+Content => "content"
+UpdatedAt => 1758000040268
+DeletedAt => 0
}
The SQL generated by the final save operation is roughly as follows
UPDATE "reports" SET "created_at"=1758000040268,"user_id"=1971482199131688960,"title"='newtitle',"subtitle"='newsubtitle',"content"='newcontent',"updated_at"=1758872959299,"deleted_at"=0 WHERE "reports"."deleted_at" = 0 AND "id" = 1967500364156506156
You can see that the user_id has been replaced with an automatically generated id value
After testing, after deleting the BeforeCreate HOOK of BaseModel, it can be updated normally
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question
template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: akkuman
solution:
func (b *BaseModel) BeforeCreate(tx *gorm.DB) (err error) {
if b.ID = 0 { b.ID = BigInt(GenerateSnowflakeID()) }
return
}