Why is there an extra insert query running for updating Many to Many field updates? [check the second last INSERT query]

I have a DB structure like the following:

type Application struct {
    BaseModel
    Name           string          `gorm:"type:text;not null;"`
    IsActive       bool            `gorm:"type:boolean;default:true;not null;index;"`
    Products       []Product       `gorm:"many2many:application_products;foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
}

type Product struct {
    BaseModel
    Name string `gorm:"type:text;unique;not null;"`
}

What am I doing?

When I'm running an update for adding a product to the Products column of the Application row, an extra INSERT query is been run which I'm not able to understand why, could anyone please help here?

LOGS

[12.482ms] [rows:1] SELECT * FROM "application_products" WHERE "application_products"."application_id" = 2

[13.729ms] [rows:1] SELECT * FROM "products" WHERE "products"."id" = 1

[33.512ms] [rows:1] SELECT * FROM "applications" WHERE uuid = 'some_uuid' and is_active = true ORDER BY "applications"."id" LIMIT 1

[1.579ms] [rows:1] SELECT * FROM "products" WHERE uuid = 'some_uuid' ORDER BY "products"."id" LIMIT 1

[0.958ms] [rows:0] INSERT INTO "products" ("created_at","updated_at","uuid","name","id") VALUES ('2022-08-10 15:18:27.21','2022-08-10 15:18:27.21','some_uuid','bank-connect',1) ON CONFLICT DO NOTHING RETURNING "id"

[1.558ms] [rows:0] INSERT INTO "application_products" ("application_id","product_id") VALUES (2,1),(2,1),(2,1) ON CONFLICT DO NOTHING

Expected answer

That INSERT query should not be running.

Comment From: github-actions[bot]

This issue has been automatically marked as stale because it has been open 360 days with no activity. Remove stale label or comment or this will be closed in 180 days

Comment From: aliforever

My Question as well

Comment From: chizidotdev

Recently ran into this issue as I kept getting duplicate key violation errors. I had a carts table with a one to many relationship with a cart_items table. Attempting to update the carts table kept performing an insert query to the order_items table with the already existing rows.

err = r.db.WithContext(ctx).
    Model(&cart).
    Updates(arg).
    Scan(cart).Error

I don't know the "why" behind this being the default behavior, but this was the fix for my use case. I had to update my code to manually omit the association during the update request.

err = r.db.WithContext(ctx).
+   Omit("CartItems").
    Model(&cart).
    Updates(arg).
    Scan(cart).Error

Comment From: GregMcDavid

2 years on and no answer?

Not really looking forward to having to intentionally add .Omit("OrderItem") to every single Save()