Laravel Lighthouse GraphQL忽略软/硬删除引发非空字段报错排查
排查方向与问题解读
关于path字段的解读
这个路径确实指向marketplaceItems列表中索引为928的元素(注意数组从0开始计数,对应列表里的第929条数据)的unit关联下的entity字段。但要注意:报错不一定是因为marketplaceItem本身被软删,更可能是它关联的unit或unit.entity被软删,导致解析关联时返回null,触发非空字段的校验错误。
具体排查方向
1. 关联模型的软删除过滤
- 检查
MarketplaceItem的unit关联、Unit的entity关联是否启用了SoftDeletestrait,且关联查询时是否自动排除软删数据。Lighthouse不会自动处理关联的软删除,需要手动配置:- 在模型关联定义中添加过滤:
public function unit() { return $this->belongsTo(Unit::class)->whereNull('deleted_at'); } - 或在GraphQL Schema的关联字段上添加指令:
unit: Unit! @where(conditions: "deleted_at is null")
- 在模型关联定义中添加过滤:
2. Lighthouse查询缓存
- 检查你的GraphQL查询是否使用了
@cache指令,若有,需清空Lighthouse的查询缓存(可通过Artisan命令php artisan lighthouse:clear-cache执行),或调整缓存有效期。
3. Laravel全局查询作用域与模型配置
- 确认
MarketplaceItem、Unit、Entity模型是否正确引入SoftDeletestrait,且没有被意外覆盖软删除的全局作用域。 - 检查是否有自定义全局作用域、本地作用域,不小心引入了
withTrashed(),导致软删数据被包含进查询结果。
4. 数据库层面验证
- 直接查询数据库,确认:
marketplace_items表中对应ID的数据deleted_at是否确实为null;- 关联的
units表、entities表中对应数据的deleted_at是否为null; - 是否存在其他查询条件(比如关联查询的join语句)导致软删数据被意外包含。
5. 关联预加载的问题
- 检查查询中是否预加载了
unit.entity,预加载逻辑是否遗漏了软删除过滤。比如是否在某个地方调用了with(['unit' => function($q) { $q->withTrashed(); }]),导致软删的unit被加载。
6. 其他缓存位置
- 外部缓存服务:若项目使用Redis、Memcached等,需清空对应缓存键(比如缓存的关联数据、查询结果);
- 数据库缓存:检查MySQL等数据库是否开启了查询缓存,手动刷新数据库缓存;
- CDN缓存:若GraphQL接口部署在CDN之后,需刷新CDN的缓存内容。
7. Lighthouse Schema指令配置
- 检查
marketplaceItems字段是否使用了@all等会返回全量数据的指令,未结合软删除过滤。建议改用@paginate或@query指定过滤后的查询,或在字段上添加@where(conditions: "deleted_at is null")指令。
内容的提问来源于stack exchange,提问作者Ruby Racer
相关产品推荐
相关产品推荐

