来自观察者的Laravel队列任务在created() 事件之后抛出ModelNotFoundException(没有查询到模型 [Invoice] 的结果)

后端开发 2026-07-09

在从Eloquent观察者派发排队作业时,我遇到了一个问题。

Error

Illuminate\Database\Eloquent\ModelNotFoundException: 
No query results for model [App\Models\Invoice]

in vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:621

#0 vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php(109): 
Illuminate\Database\Eloquent\Builder->firstOrFail()

Observer Code

public function created(OrderDeliveryOption $orderDeliveryOption): void
{
    info('orderDeliveryOption created' . $orderDeliveryOption);

    if ($orderDeliveryOption->is_custom_label) {
        Log::info('Custom label created, tracking update needed', [
            'orderDeliveryOption' => $orderDeliveryOption
        ]);
    }

    UpdateOrderParcelLithiumStatusJob::dispatch($orderDeliveryOption->id)
        ->afterCommit()
        ->delay(now()->addSeconds(5));
}

Context

  • 这段代码在 created() 观察者对 OrderDeliveryOption 的实现中运行。
  • 作业已被排队。
  • 我只传递了 $orderDeliveryOption->id,并非完整模型。
  • 但在队列处理期间,Laravel会对 App\Models\Invoice 抛出 ModelNotFoundException
  • 堆栈跟踪指向 SerializesAndRestoresModelIdentifiers.php

My Questions

  1. 为什么在我只传递了一个整数ID的情况下,Laravel还要尝试还原 Invoice
  2. 在观察者模型中加载的相关模型会引起序列化问题吗?
  3. 这个问题很可能出在Job的构造函数/属性/特性(traits)里吗?
  4. 从观察者中安全派发作业的最佳实践是什么?

Additional Notes

  • 作业使用 afterCommit()
  • 延迟时间为5 秒
  • 错误仅在从观察者调用时发生
  • 如果直接执行逻辑,则可以正常工作

我应该在Job类中检查哪些内容来修复此问题?

解决方案

首先,你不需要只把模型的ID传给作业,那是2016年的做法。

每个作业都会带有 Illuminate\Queue\SerializesModels trait,它只将模型的ID作为载荷。当作业从队列中弹出时,Laravel将使用该ID来检索模型。

其次,我认为你在作业中自己检索那张发票,而该发票已不存在。

你可以把下面这段代码放到你的作业里,以避免该作业失败:

public $deleteWhenMissingModels = true;

你能把那个 UpdateOrderParcelLithiumStatusJob 作业的完整源码贴到问题中吗?让我们看一看?

请确认我的假设是否正确,如有其他我可以帮忙的,请告诉我。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章