-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Open
Labels
type:with reproduction stepswith reproduction stepswith reproduction steps
Description
GORM Playground Link
Description
Use Clauses(clause.OnConflict{UpdateAll: true}) If the field type is struct and there is a default value which is not null, it will be ignored.
type User struct {
gorm.Model
Company Company `gorm:"default:'{}';serializer:json"`
}
func TestGORM(t *testing.T) {
user := User{Name: "jinzhu"}
DB.Create(&user)
var result User
if err := DB.First(&result, user.ID).Error; err != nil {
t.Errorf("Failed, got error: %v", err)
}
user.Company.Name = "test"
err := DB.Clauses(clause.OnConflict{UpdateAll: true}).Create(&user).Error
if err != nil {
t.Errorf("Failed upsert user: %+v", err)
return
}
err = DB.First(&result, user.ID).Error
if err != nil {
t.Errorf("Failed, got error: %v", err)
return
}
if result.Company.Name != "test" {
t.Errorf("want test, but got %s", result.Company.Name)
return
}
}The generated SQL is as follows. It can be found that the fields related to company are missing after ON CONFLICT (id) DO UPDATE SET.
INSERT INTO `users` (
`created_at`, `updated_at`, `deleted_at`,
`name`, `age`, `birthday`, `company_id`,
`manager_id`, `active`, `id`, `company`
)
VALUES
(
"2025-07-22 06:43:59.827", "2025-07-22 06:43:59.827",
NULL, "jinzhu", 0, NULL, NULL, NULL,
false, 1, "{""ID"":0,""Name"":""test""}"
) ON CONFLICT (`id`) DO UPDATE SET
`updated_at` = "2025-07-22 06:43:59.829",
`deleted_at` = `excluded`.`deleted_at`,
`name` = `excluded`.`name`,
`age` = `excluded`.`age`,
`birthday` = `excluded`.`birthday`,
`company_id` = `excluded`.`company_id`,
`manager_id` = `excluded`.`manager_id`,
`active` = `excluded`.`active` RETURNING `id`,
`company`
The problem lies in the following part: when the field is a struct and not a time field, DefaultValueInterface == nil, but here only NULL is specially judged.
https://github.com/go-gorm/gorm/blob/master/callbacks/create.go#L374
if !field.PrimaryKey && (!field.HasDefaultValue || field.DefaultValueInterface != nil || strings.EqualFold(field.DefaultValue, "NULL")) && field.AutoCreateTime == 0 {The special judgment for NULL was added in #6129 to fix the bug #5944 that I submitted earlier.
similar issue
Metadata
Metadata
Assignees
Labels
type:with reproduction stepswith reproduction stepswith reproduction steps