-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Open
Labels
Description
# Inconsistent behavior between foreignKey and joinForeignKey in Preload causing incorrect SQL JOIN field
## Description
When using struct associations in GORM, I encountered the following issue:
Dependencies:
github.com/gin-gonic/gin v1.9.1
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/google/uuid v1.5.0
golang.org/x/crypto v0.17.0
gorm.io/driver/sqlite v1.5.4
gorm.io/gorm v1.25.5
### Scenario
```go
type ChannelPartnerApp struct {
ID string `gorm:"primaryKey;type:varchar(36)" json:"id"`
ChannelPartnerID string `gorm:"type:varchar(36);not null;index" json:"channelPartnerId"`
AppID string `gorm:"type:varchar(36);not null;index;column:app_id" json:"appId"`
Key string `gorm:"type:varchar(64);not null;uniqueIndex" json:"key"`
ChannelPartner ChannelPartner `gorm:"foreignKey:ChannelPartnerID;references:ID" json:"channelPartner,omitempty"`
App App `gorm:"foreignKey:AppID;references:ID" json:"app,omitempty"`
}
type ChannelPartner struct {
ID string `gorm:"primaryKey;type:varchar(36)" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
Contact string `gorm:"type:varchar(100)" json:"contact"`
Apps []App `gorm:"many2many:channel_partner_apps;" json:"apps,omitempty"`
}
type App struct {
ID string `gorm:"primaryKey;type:varchar(36);column:id" json:"id"`
AppID string `gorm:"type:varchar(100)" json:"appId"`
ChannelPartners []ChannelPartner `gorm:"many2many:channel_partner_apps;" json:"channelPartners,omitempty"`
}
- The target table
ApphasIDas its primary key. - I am using
Preload("App")to load associated data.
Observed Behavior
- When using:
App App `gorm:"foreignKey:AppID;references:ID" json:"app,omitempty"`The generated SQL is:
[0.047ms] [rows:1] SELECT * FROM `apps` WHERE `apps`.`app_id` = "bb699b70-1787-4c7b-8b76-dd616f250cbc" AND `apps`.`deleted_at` IS NULL
SELECT * FROM `channel_partners` WHERE `channel_partners`.`id` = "2e1efe7b-f9ee-42e4-a2b4-80ac19ab7848" AND `channel_partners`.`deleted_at` IS NULL
SELECT * FROM `channel_partner_apps` WHERE channel_partner_id = "2e1efe7b-f9ee-42e4-a2b4-80ac19ab7848" AND `channel_partner_apps`.`deleted_at` IS NULL
In fact, "bb699b70-1787-4c7b-8b76-dd616f250cbc" is ChannelPartnerApp.ID, not App.ID.
- If I use:
foreignKey:ID;references:AppIDI get the correct SQL:
SELECT * FROM `apps` WHERE `apps`.`id` = "e70d3716-64a1-438a-9d91-b4b7d56a637f" AND `apps`.`deleted_at` IS NULL
Where "e70d3716-64a1-438a-9d91-b4b7d56a637f" is App.ID and matches ChannelPartnerApp.AppID.
- Using
joinForeignKey:AppIDalso produces the correct result.
Comparison with ChannelPartner
For:
ChannelPartner ChannelPartner `gorm:"foreignKey:ChannelPartnerID;references:ID" json:"channelPartner,omitempty"`Both
foreignKey:ChannelPartnerID;references:IDforeignKey:ID;references:ChannelPartnerID
produce the expected SQL:
SELECT * FROM `channel_partners` WHERE `channel_partners`.`id` = "2e1efe7b-f9ee-42e4-a2b4-80ac19ab7848" AND `channel_partners`.`deleted_at` IS NULL