← 中文资源

简体中文版本

GORM 查询时报 record not found

通过可选查询使用 Find 并显式检查错误,处理 GORM 的 ErrRecordNotFound。

阅读英文原文

症状

查询返回 record not found,调用方可能把它当作意外失败。GORM 在 First 与 Take 无匹配时返回 gorm.ErrRecordNotFound,且默认过滤软删除行。消息是准确的;问题在于对该调用点而言,缺失究竟是错误还是正常结果。

诊断

用 ToSQL 打印生成的语句确认过滤条件;缺失可接受时用 Find;检查软删除与 Unscoped。

db.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(&User{}).Where("id = ?", id).First(&u) })

根因

ORM 报告 ErrRecordNotFound,因为经默认过滤与软删除过滤后没有行匹配,而调用方把它当作错误而非预期中的空结果。

修复

缺失有效时用 Find;用 errors.Is 与 gorm.ErrRecordNotFound 比较以区分未找到与真实失败;需要包含软删除行时用 Unscoped。应在各调用点明确语义而非一刀切处理。

验证

用已知缺失与已知存在两个值分别查询确认行为符合设计,并确认软删除行仅在使用 Unscoped 时出现。两种情形都正确才算处理妥当。

常见陷阱

把所有 record not found 都当故障返回 500 会把正常的空结果误报为服务错误。