From 273cf6491f3974a385cf06b883fe0a7c8cdb0430 Mon Sep 17 00:00:00 2001 From: Krisdiano Date: Thu, 29 May 2025 19:52:36 +0800 Subject: [PATCH] feat: Ignore LastInsertID failed LastInsertID not yet supported by some database drivers. Users could avoid errors through configuration. Close https://github.com/go-gorm/gorm/issues/6343 --- callbacks/create.go | 21 +++++++++++++++++++-- gorm.go | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/callbacks/create.go b/callbacks/create.go index d8701f51..0a301eba 100644 --- a/callbacks/create.go +++ b/callbacks/create.go @@ -1,6 +1,7 @@ package callbacks import ( + "database/sql/driver" "fmt" "reflect" "strings" @@ -68,8 +69,8 @@ func Create(config *Config) func(db *gorm.DB) { db.Statement.Build(db.Statement.BuildClauses...) } - isDryRun := !db.DryRun && db.Error == nil - if !isDryRun { + notDryRun := !db.DryRun && db.Error == nil + if !notDryRun { return } @@ -126,6 +127,22 @@ func Create(config *Config) func(db *gorm.DB) { insertOk := err == nil && insertID > 0 if !insertOk { + if db.Config.IgnoreLastInsertIDWhenNotSupport { + _, rowsAffectedErr := driver.RowsAffected(0).LastInsertId() + if strings.Compare(err.Error(), rowsAffectedErr.Error()) == 0 { + return + } + _, resultNoRowsErr := driver.ResultNoRows.LastInsertId() + if strings.Compare(err.Error(), resultNoRowsErr.Error()) == 0 { + return + } + if db.Config.IsNotSupportLastInsertIDErr != nil && db.Config.IsNotSupportLastInsertIDErr(err) { + return + } + if db.Logger != nil { + db.Logger.Warn(db.Statement.Context, "Failed to get last insert ID, err: %v", err) + } + } if !supportReturning { db.AddError(err) } diff --git a/gorm.go b/gorm.go index 67889262..d1e10fbb 100644 --- a/gorm.go +++ b/gorm.go @@ -24,6 +24,12 @@ type Config struct { SkipDefaultTransaction bool DefaultTransactionTimeout time.Duration + // Not all database support LastInsertId, you can set `IgnoreLastInsertIDWhenNotSupport` to true in those cases + IgnoreLastInsertIDWhenNotSupport bool + // When 'IgnoreLastInsertIDWhenNotSupport' is true, you can set `IsNotSupportLastInsertIDErr` to check if the error is 'NotSupportLastInsertID' + // Gorm only asserts the type of returned sql/driver.Result if 'IsNotSupportLastInsertIDErr' is not set. + IsNotSupportLastInsertIDErr func(error) bool + // NamingStrategy tables, columns naming strategy NamingStrategy schema.Namer // FullSaveAssociations full save associations