-
Type:
Question
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
None
-
None
-
None
-
None
-
None
-
None
ahmdadl has created Issue #3549: In-memory model hydration bug masks id after Model::create() in laravel-mongodb. This Jira ticket was filed by GromNaN
Issue Text:
- Laravel-mongodb Version: 5.8.2
- PHP Version: 8.3 / 8.4
- Database Driver & Version: MongoDB (Custom Connection Extension)
Description:
The integer `id` manually generated and assigned inside the `creating` model event works perfectly upon database insertion and subsequent retrieval via queries (e.g., `::find()`, `::first()`). However, *immediately following a `Model::create()` operation*, the returned in-memory model instance drops the custom integer `id` value when serialized via `toArray()`, replacing it with the auto-generated MongoDB hexadecimal `_id` string instead.
Steps to reproduce
1. Extend the database connection to map a custom Mongo connection handling integer primary keys in `AppServiceProvider`:
```php
use Illuminate\Support\Facades\DB;
DB::extend("mongodb", function ($config, $name) {
$config["name"] = $name;
return new CustomMongoConnection($config);
});
DB::purge("mongodb");
```
2. Define the model targeting the custom primary key and hooks:
```php
use MongoDB\Laravel\Eloquent\Model;
class Request extends Model
{
protected $connection = 'mongodb';
protected $primaryKey = 'id';
protected $keyType = 'int';
protected static function booted(): void
{
static::creating(function ($model) {
$generateId = fn() => random_int(100000000, 999999999);
$modelId = $generateId();
if (!$model->id)
{ $model->id = $modelId; } $model->cid = $modelId;
});
}
}
```
3. Execute a `create()` command and compare the inline model output with a freshly queried document model instance:
```php
$request = Request::create([]);
dump($request->toArray());
$fetchedRequest = Request::latest()->first();
dd($fetchedRequest->toArray());
```
Expected behaviour
Both `toArray()` outputs should yield identical structures, retaining the assigned integer `id` attribute without mutating it post-save.
```php
array:5 [
"_id" => "6a5e0a40a3c1417750053505"
"id" => 285028729
"cid" => 285028729
"updated_at" => "2026-07-20T11:45:04.368000Z"
"created_at" => "2026-07-20T11:45:04.368000Z"
]
```
Actual behaviour
The model returned directly from `Request::create()` masks the integer `id` with the MongoDB `_id` string, while the fetched model displays the correct attributes:
*Output 1: Freshly created instance (`dump($request->toArray());`)*
```php
array:4 [
"id" => "6a5e0a40a3c1417750053505" // BUG: Overwritten by MongoDB string _id, integer value lost in memory
"cid" => 285028729
"updated_at" => "2026-07-20T11:45:04.368000Z"
"created_at" => "2026-07-20T11:45:04.368000Z"
]
```
*Output 2: Freshly fetched from DB (`dd($fetchedRequest->toArray());`)*
```php
array:5 [
"_id" => "6a5e0a40a3c1417750053505"
"id" => 285028729 // Works perfectly here!
"cid" => 285028729
"updated_at" => "2026-07-20T11:45:04.368000Z"
"created_at" => "2026-07-20T11:45:04.368000Z"
]
```
<details><summary><b>Logs</b>:</summary>
No exception is thrown. The bug is limited to an inconsistent internal state mapping on the `Eloquent\Model` attribute dictionary immediately following a `save()` pipeline operation.
</details>