go-xorm / xorm

Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm
BSD 3-Clause "New" or "Revised" License
6.67k stars 754 forks source link

Handler crashed with error runtime error: hash of unhashable type models.Device #682

Open zxysilent opened 7 years ago

zxysilent commented 7 years ago

不确定是不是 xorm 的bug 使用了

sess := Db.NewSession()
defer sess.Close()
sess.Begin()

出现下面问题 Handler crashed with error runtime error: hash of unhashable type models.Device

1 1 <nil> 3 <nil> 设备名称 规格 38 [] 品牌 资产编号 型号 2017-08-10 16:35:27 +0800 CST 2017-08-10 16:35:27 +0800 CST 性质i 联系人 18284151024 地点11111 特色 费用 设备 0 0001-01-01 00:00:00 +0000 U
TC 0001-01-01 00:00:00 +0000 UTC 0}
[xorm] [info]  2017/08/11 10:50:38.619908 [sql] UPDATE `device` SET `stl_id` = ?, `adm_id` = ?, `name` = ?, `spec` = ?, `fids` = ?, `brand` = ?, `num` = ?, `model` = ?, `ptime` = ?, `gtime` = ?, `t
ype` = ?, `contact` = ?, `phone` = ?, `place` = ?, `fun` = ?, `costdesc` = ?, `desc` = ?, `utime` = ? WHERE `id`=? [args] [1 3 设备名称 规格 38 品牌 资产编号 型号 2017-08-10 16:35:27 2017-08-10 16:
35:27 性质i 联系人 18284151024 地点11111 特色 费用 设备 2017-08-11 10:50:38 1] - took: 3.9993ms
2017/08/11 10:50:38 [C] [asm_amd64.s:509] the request url is  /m/device/dedit
2017/08/11 10:50:38 [C] [asm_amd64.s:509] Handler crashed with error runtime error: hash of unhashable type models.Device
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/asm_amd64.s:509
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/panic.go:491
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/alg.go:166
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/hashmap.go:538
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Appdata/Go/src/github.com/go-xorm/xorm/session.go:3692
2017/08/11 10:50:38 [C] [asm_amd64.s:509] I:/App/Go/src/share/models/device.go:115
2017/08/11 10:50:38 [C] [asm_amd64.s:509] I:/App/Go/src/share/controllers/managers/device.go:342
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/asm_amd64.s:509
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/reflect/value.go:434
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/reflect/value.go:302
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Appdata/Go/src/github.com/astaxie/beego/router.go:815
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/net/http/server.go:2619
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/net/http/server.go:1801
2017/08/11 10:50:38 [C] [asm_amd64.s:509] D:/Program Files/Go/src/runtime/asm_amd64.s:2337

如果不用 直接使用Db 则没有错误

lunny commented 7 years ago

models.Device 结构体可以贴下?

zxysilent commented 7 years ago
type Device struct {
    Id int `xorm:"pk autoincr INT(11)"`
    StlId    int       `xorm:"INT(11)"`
    Style    *Style    `xorm:"-"`
    AdmId    int       `xorm:"INT(11)"`      // 单位负责人
    Admin    *Admin    `xorm:"-"`            //
    Name     string    `xorm:"VARCHAR(255)"` // 设备名称
    Spec     string    `xorm:"VARCHAR(255)"` // 规格
    Fids     string    `xorm:"VARCHAR(255)"` // 图片集合
    Files    []*File   `xorm:"-"`
    Brand    string    `xorm:"VARCHAR(255)"` // 品牌
    Num      string    `xorm:"VARCHAR(255)"` // 资产编号
    Model    string    `xorm:"VARCHAR(255)"` // 型号
    Ptime    time.Time `xorm:"DATETIME"`     // 出厂日期
    Gtime    time.Time `xorm:"DATETIME"`     // 购买日期
    Type     string    `xorm:"VARCHAR(255)"` // 使用性质
    Contact  string    `xorm:"VARCHAR(255)"` // 联系人
    Phone    string    `xorm:"VARCHAR(255)"` // 联系人电话
    Place    string    `xorm:"VARCHAR(255)"` // 放置地点
    Fun      string    `xorm:"VARCHAR(255)"` // 功能及特色
    Costdesc string    `xorm:"VARCHAR(512)"` // 费用描述
    Desc     string    `xorm:"VARCHAR(512)"` // 设备描述
    Count    int       `xorm:"INT(11)"`      // 使用次数
    Utime    time.Time `xorm:"updated"`
    Ctime    time.Time `xorm:"created"`
    Status   int8      `xorm:"TINYINT(4)"` // 状态标识
}
lunny commented 7 years ago

你的版本?

zxysilent commented 7 years ago

go 1.9 // Version show the xorm's version Version string = "0.6.0.1022"

lunny commented 7 years ago

更新到最新版本再试下?

zxysilent commented 7 years ago

同样的问题 // Version show the xorm's version Version string = "0.6.3.0713"

meilihao commented 5 years ago

我也遇到了这个问题, 也是在事务里, 使用的是pg:

log:

[xorm] [info]  2019/04/03 18:09:06.756335 [SQL] INSERT INTO "customer_profile" ("group_id","phone","name","belong","expand","status","created_at","updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) []interface {}{1, "1007", "test", "test", "{\"keys\":[],\"values\":[]}", 1, "2019-04-03 18:09:06", "2019-04-03 18:09:06"}
[xorm] [info]  2019/04/03 18:09:06.756629 [SQL] ROLL BACK
panic: runtime error: hash of unhashable type model.CustomerProfile

goroutine 9 [running]:
github.com/go-xorm/xorm.(*Session).innerInsert.func1(0xd156e0, 0xc000360000)
    /home/chen/git/go/src/github.com/go-xorm/xorm/session_insert.go:411 +0x1b9
github.com/go-xorm/xorm.(*Session).innerInsert(0xc00017b8f8, 0xd156e0, 0xc000360000, 0x1, 0x0, 0x0)
    /home/chen/git/go/src/github.com/go-xorm/xorm/session_insert.go:532 +0x195d
github.com/go-xorm/xorm.(*Session).Insert(0xc00017b8f8, 0xc00017b6a8, 0x1, 0x1, 0x0, 0x0, 0x0)
    /home/chen/git/go/src/github.com/go-xorm/xorm/session_insert.go:83 +0x5bc
gitee.com/fuyu008/robot-web/model.HandleOutboundResult(0xc000304000, 0x0, 0x0)
    /home/chen/git/go/src/gitee.com/fuyu008/robot-web/model/mq.go:139 +0x1600

我的struct:

type CustomerProfile struct {
    GroupId   int       `xorm:"pk" json:"group_id"`
    Phone     string    `xorm:"pk" json:"phone"`
    Name      string    `json:"name"`
    Belong    string    `json:"belong"`
    Expand    KVExpand  `xorm:"json" json:"expand"`
    Status    int       `json:"-"`
    CreatedAt time.Time `xorm:"created" json:"-"`
    UpdatedAt time.Time `xorm:"updated" json:"-"`
}

// 客户资料, 以kv形式保存
type KVExpand struct {
    Keys   []string `json:"keys"`
    Values []string `json:"values"`
}

已使用了最新版617e0ae295d7fd8a4ea48f6c782781f6cc367c7e.

解决了: 将CustomerProfile.Expand定义为*KVExpand即可正确计算hash值.

参考: Go语言之自定义集合Set