I've read the entire internet about the
Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Ticket] raised by a failed job that uses SerializeModelstrait.
The strange thing is that ModelNotFoundException is raised even if the Model 100% exists on the database. I tried to deserialize the payloadfrom the failed_jobstable and search one-by-one the primary keys and all exist in the database. There is a transaction in my code and AFTER it commits i raise some events that fires the same job. No way that the PK of Eloquent Models to be null because i do not create new models inside a transaction but i use existing models.
ModelNotFoundException from __wakeupI setup a listener for some events and every time i dispatch a job. The parameter for the job is a class that implements INotificationEvent interface.

Does it work if you just pass the id to the job and refetch the model there in?
Are you dispatching the job within a transaction? I had a similar issue where I was dispatching an event inside a transaction which hadn't been commited yet when the queue picked up the event.
Closing this issue because it's inactive, already solved, old or not relevant anymore. Feel free to reply if you're still experiencing this issue.
Sorry for the delay....
This is the job

and the contrsuctor parameter INotificationEvent $event is an object that holds existing eloquent models.
From the code of SerializeModels i understand that when the job is queued in Redis is serialized and that is:
INotificationEvent $event is traversed and serialized. If one or more properties are Eloquent Models are serialized in a special way as new ModelIdentifier.In the deserialization process although ModelIdentifier points to an existing Id, without the delay at the job always ModelNotFoundException raised.
I am raising events and dispatch jobs after i commit the transaction. But either way, the models are not new...are just models that already existed in the database
I am asking if there is a special case where a model deserialization might not work as expected.
So what I believe is happening is that you're trying to serialize an object containing models. This isn't wanted I believe with the SerializeModels trait. I think it only works if you try to serialize models directly as a property on the job. If you want to serialize other objects I believe you should only use scalars like model ids and retrieve them yourselves.
Btw, the hint is in the trait's name. It only serializes models and no other objects.
This is all the classes involved a complete example
interface INotificationEvent
{
public function getTicket();
public function getUser();
}
class NotificationEventBase extends Event
{
public $ticket = null; //Eloquent Model
public $user = null; //Eloquent Model
public function __construct() {
}
public function load(int $ticket_id, int $user_id)
{
$this->ticket=loadTicketFromDb($ticket_id);
$this->user=loadUserFromDb($user_id);
}
public function getUser() {
return $this->user;
}
public function getTicket() {
return $this->ticket;
}
}
class TicketCreated extends NotificationEventBase implements INotificationEvent
{
use SerializesModels;
public function __construct(int $ticket_id, int $user_id) {
parent::load($ticket_id, $user_id);
}
}
class NotificationEngineJob implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
public $payload = null;
public function __construct(INotificationEvent $payload) {
$this->payload = $payload;
}
public function handle() {
//Somw code to handle
}
}
///*******************************************************
///------------------ Finally --------------------------//
///*******************************************************
$data=new TicketCreated(1,2);
$job=(new NotificationEngineJob($data))->delay(60);
dispatch($job);
This does still seem to exist as of v7.28.3.
I dispatch a job from a model observer's created event that accepts the newly created model. If I only create a few models, the jobs dispatch fine. Running code that creates 100s of models which dispatches 100s of jobs using the new models is where the problem occurs.
The jobs all run fine if I retry from Horizon so I don't believe it's a code problem.
#1 /home/forge/site.com/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php(57): App\Jobs\SendWebHook->restoreModel()
The error occurs during restore which leads me to believe the new models aren't available in the database yet.
namespace App\Jobs;
use App\Models\Webhook;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
class SendWebHook implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 0;
public $maxExceptions = 3;
protected Model $model;
protected string $event;
protected ?array $changed_from;
protected ?array $changed_to;
/**
* Create a new job instance.
*
* @param Model $model
* @param string $event
* @param array $changed_from
* @param array $changed_to
*/
public function __construct(Model $model, string $event, ?array $changed_from, ?array $changed_to)
{
$this->model = $model;
$this->event = $event;
$this->changed_from = $changed_from;
$this->changed_to = $changed_to;
}
public function retryUntil()
{
return now()->addHours(1);
}
public function handle()
{
\Log::info(json_encode($this->model->getAttributes());
}
}
The failure isn鈥檛 a problem, it should fail if the model isn鈥檛 available. The problem I see is the jobs don鈥檛 retry automatically as they should with $maxExceptions 3 and retryUntil() 1 hour from now. It seems the model not found exception automatically fails jobs?
Most helpful comment
Are you dispatching the job within a transaction? I had a similar issue where I was dispatching an event inside a transaction which hadn't been commited yet when the queue picked up the event.