简体   繁体   中英

Laravel 9 - Eloquent model : Trying to load self model parents recursively

I'm trying to migrate a Laravel 5 API with MySQL 5.7 to a Laravel 9 API with MySQL 8.

Almost everything is working well, except on a few queries that tries to load data with their parent, recursively.

On Laravel 5, i came up with this following solutions: Recursive Eloquent Models | Laravel ORM from self referencing table get N level hierarchy JSON

It was working like a charm, but on Laravel 9, I get a HTTP 500 error from Apache, which tells me in the logs the following error:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes)

I tried at first to increase the memory in php.ini, but it was getting worst as the server was getting very laggy, so I had to restart Apache and go back with the 128M default value. Also on my Laravel 5 environment, I did not need to increase memory.

I was also suspecting the MySQL 8 upgrade to be involved in this problem, but by connecting to my MySQL 5.7 database, i had the same issue, so I think it comes from the way that Laravel loads relations in the 9 version.

Here is my Model code:

<?php
  namespace App\Models\Consommation;

  use Illuminate\Database\Eloquent\Model;

  class ConsoRequestAttribut extends Model
  {
    protected $table = 'conso_request_attribut';
    public $incrementing = false;
    protected $primaryKey = 'id_attribut';
    public $timestamps = false;

    const ERROR_DELETE_ATTRIBUTE = 1;
    const SUCCESS_DELETE_ATTRIBUTE = 0;

    protected $fillable = [
        'id_attribut',
        'code_type_attribut',
        'valeur',
        'id_parent_attribut'
    ];

    public function parent_attribut() {
        return $this->belongsTo('App\Models\Consommation\ConsoRequestAttribut', 'id_parent_attribut', 'id_attribut');
    }

    public function parent() {
        return $this->parent_attribut()->with('parent');
    }

    ...
   }

So on my Laravel 9 app, if I remove the ->with('parent') in my parent() function, the query result is returned and I don't have a 500 HTTP error, so I think the problem is with recursive loading.

Any idea?

Thanks

It is better to call nested relationships like this:

public function parent() {
    return $this->with('parent_attribut.parent');
}

I did not succeed to load the parent entity recursively with my ConsoRequestAttribut model, as I'm still stuck with the same memory problem. So it's not really "resolved".

As an alternative, in my ConsoRequestAttributRepository class, I made a function to load parent of entity recursively, which works perfectly:

public function retrieveRecursivelyConsoRequestAttributeParent(ConsoRequestAttribut $attribut)
{
    $parent = ConsoRequestAttribut::where('id_attribut', $attribut->id_parent_attribut)
        ->first();

    $attribut->parent = $parent;

    if($parent->id_parent_attribut != null)
        $this->retrieveRecursivelyConsoRequestAttributeParent($parent);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM