Skip to content

Jsonb field of association isn't properly saved if it has default specified #6418

Open
@jivot

Description

@jivot

GORM Playground Link

go-gorm/playground#620

Description

type ValueDep struct {
	gorm.Model

	ID      int `gorm:"primarykey,autoIncrement"`
	ValueID int
	Name    string `gorm:"column:name; default:'default'"`
	Params  Params `gorm:"column:params; type:jsonb; default:'{}'"`
}

type Value struct {
	gorm.Model

	ID   int         `gorm:"primarykey,autoIncrement"`
	Deps []*ValueDep `gorm:"foreignKey:ValueID"`
}

type Params map[string]string

func (p *Params) Scan(val interface{}) error {
	switch v := val.(type) {
	case []byte:
		return json.Unmarshal(v, p)
	case string:
		return json.Unmarshal([]byte(v), p)
	default:
		return fmt.Errorf("unsupported type: %T", v)
	}
}

func (p Params) Value() (driver.Value, error) {
	return json.Marshal(p)
}

Steps to reproduce:

var value Value
// read value from the db

// assign new values to the map
value.Deps[0].Params["foo"] = "new-bar"

// save the struct to the db
DB.Session(&gorm.Session{FullSaveAssociations: true}).Save(value)

SQL which is supposed to update association will look like this

INSERT INTO "value_deps" ("created_at","updated_at","deleted_at","value_id","name","params","id") VALUES ('2023-06-16 20:10:28.427','2023-06-16 20:10:28.444',NULL,11,'new-name','{"foo":"new-bar"}',11) ON CONFLICT ("id") DO UPDATE SET "updated_at"='2023-06-16 20:10:28.444',"deleted_at"="excluded"."deleted_at","value_id"="excluded"."value_id","name"="excluded"."name" RETURNING "id","params","id"

Notice, that the params field isn't listed in the SET clause. Which means that this sql will work correctly only if we're inserting a new association. If we're trying to update an existing one the new-bar value will be lost.

This happens only if we specify default:'{}' option. Without it the save will work ok

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions