GORM Playground Link
https://github.com/go-gorm/playground/pull/817
Description
When defining a self-referential belongs to relationship where both the primary key and the foreign key field are of type uuid.UUID, AutoMigrate incorrectly generates the foreign key column with a bigint type instead of the specified uuid type.
This issue appears to be triggered specifically by the presence of the struct field that defines the relationship. If the relationship field (e.g., Creator *User) is commented out, the foreign key column (created_by) is correctly migrated with a uuid type.
This behavior contradicts the expected outcome and persists even when following the official documentation for resolving relationship ambiguity by using the references tag.
What I've tried:
1. Base Model:
go
type User struct {
ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey"`
Name string `gorm:"not null"`
CreatedBy uuid.UUID `gorm:"type:uuid;not null"`
}
With this model, AutoMigrate correctly creates the created_by column as uuid.
-
Adding the
belongs torelationship:go type User struct { ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey"` Name string `gorm:"not null"` CreatedBy uuid.UUID `gorm:"type:uuid;not null"` Creator *User `gorm:"foreignKey:CreatedBy"` // This line triggers the bug }This causesAutoMigrateto generatecreated_byasbigint. -
Adding
references:IDas per documentation:go Creator *User `gorm:"foreignKey:CreatedBy;references:ID"`This does not fix the issue; the column type remainsbigint. -
Adding type:uuid to the relationship field:
go Creator *User `gorm:"foreignKey:CreatedBy;references:ID;type:uuid"`This results in another incorrect behavior: GORM attempts to create an additional, unwanted column namedcreatorof typeuuid, while thecreated_bycolumn remainsbigint.
This appears related to previously reported issues like #6862 and #7191, which describe foreign keys incorrectly inheriting types or causing type inference problems, but those were closed without resolution.
Expected Behavior
AutoMigrate should generate a CREATE TABLE statement where the created_by column is of type uuid and with a foreign key constraint pointing to the id column of the same table.
Example (for PostgreSQL):
CREATE TABLE "users" (
"id" uuid DEFAULT gen_random_uuid(),
"name" text NOT NULL,
"created_by" uuid NOT NULL,
CONSTRAINT "fk_users_creator" FOREIGN KEY ("created_by") REFERENCES "users"("id")
)
Actual Behavior
GORM's logger shows that AutoMigrate generates a CREATE TABLE statement where the created_by column is incorrectly defined as bigint.
Actual Log Output (from PostgreSQL):
CREATE TABLE "users" (
"id" uuid DEFAULT gen_random_uuid(),
"name" text NOT NULL,
"created_by" bigint,
CONSTRAINT "fk_users_creator" FOREIGN KEY ("created_by") REFERENCES "users"("id")
)
Environment GORM version: gorm.io/gorm v1.30.0 GORM postgres driver version: gorm.io/driver/postgres v1.6.0 Go version: go version go1.24.1 Database: postgres
Comment From: jj10052
I'm having the same issue without self-references. The issue is the foreignKey name. If the foreignKey name is also used in the referenced struct, migrations will change the type to bigint. With self-reference the same issue occurs, because the referenced struct obviously has the same fields.
The following does not work, because Company has a field named SomeKey, which is the same name used in User to reference Company.
type User struct {
gorm.Model
Name string
SomeKey int
Company Company `gorm:"foreignKey:SomeKey"`
}
type Company struct {
ID int
SomeKey int
Name string
}
Even when using the field tag references, the same issue occurs:
type User struct {
gorm.Model
Name string
SomeKey int
Company Company `gorm:"foreignKey:SomeKey;references:ID"`
}
type Company struct {
ID int
SomeKey int
Name string
}
This works, because the field name used for reference is not used in Company.
type User struct {
gorm.Model
Name string
SomeKey int
Company Company `gorm:"foreignKey:SomeKey"`
}
type Company struct {
ID int
AnotherKey int
Name string
}