session.Insert(&[]interface{}) session.Commit() panic: reflect: call of reflect.Value.Field on interface Value #2259

Closed
opened 2023-05-10 13:39:16 +00:00 by Abei1uo · 1 comment
Contributor
No description provided.
ver: go1.19.8 xorm.io/xorm v1.3.2 github.com/go-sql-driver/mysql v1.7.1 当表结构体使用Column属性 created和updated, 执行session.Insert(&[]interface{})后,在session.Commit()时发生panic SQL日志显示事务已提交 报错位置 [https://gitea.com/xorm/xorm/src/commit/94fcec7f65f87b4a227f2b45b6947247a6f0208d/session_insert.go#L162] [(https://gitea.com/xorm/xorm/src/commit/94fcec7f65f87b4a227f2b45b6947247a6f0208d/schemas/column.go#L93)] 报错测试用例代码如下: > func TestInsertMulti2InterfaceTransaction(t *testing.T) { type User struct { ID uint64 `xorm:"id pk autoincr"` Name string Alias string CreateTime time.Time `xorm:"created"` UpdateTime time.Time `xorm:"updated"` } assert.NoError(t, PrepareEngine()) assertSync(t, new(User)) session := testEngine.NewSession() defer session.Close() err := session.Begin() assert.NoError(t, err) users := []interface{}{ &User{Name: "a", Alias: "A"}, &User{Name: "b", Alias: "B"}, &User{Name: "c", Alias: "C"}, &User{Name: "d", Alias: "D"}, } cnt, err := session.Insert(&users) assert.NoError(t, err) assert.EqualValues(t, len(users), cnt) err = session.Commit() assert.NoError(t, err) } 附报错堆栈: > [xorm] [info] 2023/05/10 21:23:05.229541 [SQL] BEGIN TRANSACTION [] [xorm] [info] 2023/05/10 21:23:05.230541 [SQL] INSERT INTO `user` (`name`,`alias`,`create_time`,`update_time`) VALUES (?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?),(?, ?, ?, ?) [a A 2023-05-10 13:23:05 2023-05-10 13:23:05 b B 2023-05-10 13:23:05 2023-05-10 13:23:05 c C 2023-05-10 13:23:05 2023-05-10 13:23:05 d D 2023-05-10 13:23:05 2023-05-10 13:23:05] - 1ms [xorm] [info] 2023/05/10 21:23:05.362549 [SQL] COMMIT [] - 132.0076ms --- PASS: TestInsertMulti2InterfaceTransaction/user (0.13s) panic: reflect: call of reflect.Value.Field on interface Value [recovered] panic: reflect: call of reflect.Value.Field on interface Value goroutine 20 [running]: testing.tRunner.func1.2({0x1dc0ce0, 0xc0000a8360}) E:/go/go1.19.8/src/testing/testing.go:1396 +0x485 testing.tRunner.func1() E:/go/go1.19.8/src/testing/testing.go:1399 +0x616 panic({0x1dc0ce0, 0xc0000a8360}) E:/go/go1.19.8/src/runtime/panic.go:890 +0x267 reflect.Value.Field({0x1dbb8e0, 0xc0000ae440, 0x194}, 0x3) E:/go/go1.19.8/src/reflect/value.go:1266 +0x26f reflect.Value.FieldByIndex({0x1dbb8e0, 0xc0000ae440, 0x194}, {0xc000069778, 0x1, 0x1}) E:/go/go1.19.8/src/reflect/value.go:1299 +0xbc xorm.io/xorm/schemas.(*Column).ValueOfV(0xc0000a2f00, 0xc000069880) E:/GWS/xorm/schemas/column.go:93 +0x28b xorm.io/xorm/schemas.(*Column).ValueOf(0xc0000a2f00, {0x1d86180, 0xc0000ae440}) E:/GWS/xorm/schemas/column.go:80 +0xaf xorm.io/xorm.setColumnTime({0x1d86180, 0xc0000ae440}, 0xc0000a2f00, {0xdae8618, 0xedbed91b9, 0x24d0b60}) E:/GWS/xorm/session_cols.go:31 +0x85 xorm.io/xorm.(*Session).insertMultipleStruct.func1({0x1d86180, 0xc0000ae440}) E:/GWS/xorm/session_insert.go:162 +0x9b xorm.io/xorm.(*Session).Commit.func1(0xc0000a82e8, {0x1d86180, 0xc0000ae440}) E:/GWS/xorm/session_tx.go:50 +0x9f xorm.io/xorm.(*Session).Commit(0xc000032f70) E:/GWS/xorm/session_tx.go:56 +0x1f2 xorm.io/xorm/integrations.TestInsertMulti2InterfaceTransaction(0xc0001769c0) E:/GWS/xorm/integrations/session_tx_test.go:219 +0x832 testing.tRunner(0xc0001769c0, 0x1ef8358) E:/go/go1.19.8/src/testing/testing.go:1446 +0x1ca created by testing.(*T).Run E:/go/go1.19.8/src/testing/testing.go:1493 +0x69e 可行的解决办法 在 [(https://gitea.com/xorm/xorm/src/commit/94fcec7f65f87b4a227f2b45b6947247a6f0208d/schemas/column.go#L93)] 函数func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) 中添加interface的判断 > if v.Kind() == reflect.Interface { v = reflect.Indirect(v.Elem()) } > func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) { v := *dataStruct for _, i := range col.FieldIndex { if v.Kind() == reflect.Ptr { if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) } v = v.Elem() }else if v.Kind() == reflect.Interface { //增加对interface的类型判断 v = reflect.Indirect(v.Elem()) } v = v.FieldByIndex([]int{i}) } return &v, nil }
lunny added the
kind
bug
label 2023-05-11 03:40:45 +00:00
Owner

closed by #2260

closed by #2260
lunny closed this issue 2023-07-23 02:58:41 +00:00
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: xorm/xorm#2259
No description provided.