Search code examples
gogo-gorm

GORM: Reference replaced with random values


I have database structure:

type User struct {
    db.Base
    Username string `gorm:"unique;not null" json:"username"`
    Password string `gorm:"not null" json:"password"`
    FullName string `gorm:"not null" json:"full_name"`
    Email    string `gorm:"unique;not null" json:"email"`
}

And Account DB structure:

type Account struct {
    db.Base
    UserID   uuid.UUID `gorm:"not null" json:"user_id"`
    User     user.User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"user"`
    Name     string    `gorm:"not null" json:"name"`
    Currency string    `gorm:"not null" json:"currency"`
}

The Base looks like:

type Base struct {
    ID        uuid.UUID  `gorm:"type:uuid;primary_key;" json:"id"`
    CreatedAt time.Time  `json:"created_at"`
    UpdatedAt time.Time  `json:"updated_at"`
    DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}

func (base *Base) BeforeCreate(db *gorm.DB) error {
    v4 := uuid.NewV4()
    db.Set("ID", v4)
    base.ID = v4
    return nil
}

But when i tried to insert new value:

func Add(u *user.User) (account Account, err error) {
    account = Account{
        User:     *u,
        UserID:   u.ID,
        Currency: currency.EUR.String(),
        Name:     "Default",
    }
    err = consts.DB.Model(&Account{}).Save(&account).Error
    return account, err
}

The error drops:

ERROR: insert or update on table "accounts" violates foreign key constraint "fk_accounts_user" (SQLSTATE 23503)
[9992.860ms] [rows:0] INSERT INTO "accounts" ("created_at","updated_at","deleted_at","user_id","name","currency","id") VALUES ('2023-01-30 14:55:20.261','2023-01-30 14:55:20.261',NULL,'f5e6984d-4945-4a90-9085-4d6b9d94a8c8','Default','EUR','74943fc5-d767-4e52-8044-d0e9e26e4568') RETURNING "id"
[GIN] 2023/01/30 - 14:55:21 | 400 |         4m56s |             ::1 | POST     "/api/v1/accounts"

In every request the reference uuid is different. On 27 of the Add function the Id and User is correct. But after saving attempt - UserID is random UUID.


Solution

  • The problem was in method BeforeCreate:

    func (base *Base) BeforeCreate(db *gorm.DB) error {
        v4 := uuid.NewV4()
        db.Set("ID", v4)
        base.ID = v4
        return nil
    }
    

    It generated a new ID for each entity each time a record was created, and along with it, new IDs for all references How to fix? In the Base class, add an ID field of type UUD tag default:

    ID        uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid();" json:"id"`
    

    Here gen_random_uuid() is internal PostgreSQL method available from, v14 (not sure)