Contain depth restriction?

I have a Chargers table, and the entities in that table can be replaced by other Chargers, so I have a replacement_id field that defaults to null.

When the charger is set to be replaced, the replacement_id is set to the newly created Charger entity id. I want to make an overview of the replacement history of a charger, so I’ve set up a hasOne association in the ChargersTable named Originals that maps to the Chargers table.

So in the ChargersTable I have a find method named findHistory that looks like this:

public function findHistory(Query $query): Query
{
    return $query->contain('Originals.Originals.Originals.Originals.Originals');
}

With this method I should get the original charger up to 5 times. The SQL panel in DebugKit reflects this with the queries, but only two original fields are loaded into the entity.

Is there a depth limit for contain?

Code extracts under:

ChargersTable.php

<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\Table;

/**
 * Chargers Model
 *
 * @mixin \Cake\ORM\Behavior\TimestampBehavior
 */
class ChargersTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('chargers');
        $this->setDisplayField('serial');
        $this->setPrimaryKey('id');

        $this->hasOne('Originals', [
            'className' => 'Chargers',
            'foreignKey' => 'replacement_id',
        ]);
    }

    /**
     * Find history for chargers. Contains its replacements and originals up to a depth of 5 each.
     *
     * @param \Cake\ORM\Query $query Query.
     * @return \Cake\ORM\Query
     */
    public function findHistory(Query $query): Query
    {
        return $query->contain('Originals.Originals.Originals.Originals.Originals.Originals');
    }
}

ChargersController:

<?php
declare(strict_types=1);

namespace App\Controller;

/**
 * Chargers Controller
 *
 * @property \App\Model\Table\ChargersTable $Chargers
 * @method \App\Model\Entity\Charger[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class ChargersController extends AppController
{
    /**
     * See the replacement history for a charger
     *
     * @param string|null $id Charger id
     * @return void
     */
    public function history(?string $id = null): void
    {
        $charger = $this->Chargers->get($id, [
            'finder' => 'history',
        ]);

        $this->set(compact('charger'));
    }
}
-- phpMyAdmin SQL Dump
-- version 5.2.0
-- https://www.phpmyadmin.net/
--
-- Host: localhost
-- Generation Time: 20. Aug, 2023 22:03 PM
-- Tjener-versjon: 10.4.13-MariaDB
-- PHP Version: 8.1.7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `chargers`
--

-- --------------------------------------------------------

--
-- Tabellstruktur for tabell `chargers`
--

CREATE TABLE `chargers` (
  `id` int(11) NOT NULL,
  `serial` varchar(255) NOT NULL,
  `replacement_id` int(11) DEFAULT NULL COMMENT 'What charger replaced this one'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

--
-- Dataark for tabell `chargers`
--

INSERT INTO `chargers` (`id`, `serial`, `replacement_id`) VALUES
(80, '#5', NULL),
(79, '#4', 80),
(78, '#3', 79),
(77, '#2', 78),
(76, '#1', 77);

--
-- Indexes for dumped tables
--

--
-- Indexes for table `chargers`
--
ALTER TABLE `chargers`
  ADD PRIMARY KEY (`id`),
  ADD KEY `replacement_id` (`replacement_id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `chargers`
--
ALTER TABLE `chargers`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=81;

image

This is the Charger entity set in controller, after using disableHydration():

image