Typed nullable @ManyToOne must not be accessed before initialization #6464

Open
opened 2026-01-22 15:33:39 +01:00 by admin · 2 comments
Owner

Originally created by @vudaltsov on GitHub (May 12, 2020).

Bug Report

Q A
BC Break no
Version 2.7.2

Summary

part of an entity:

/**
 * @ORM\Entity()
 */
class Process
{
    /**
     * @ORM\ManyToOne(targetEntity=Process::class)
     * @ORM\JoinColumn()
     */
    private ?self $parentProcess;

    public function __construct(?self $parentProcess = null)
    {
        $this->parentProcess = $parentProcess;
    }

    private function isRoot(): bool
    {
        return null === $this->parentProcess;
    }
}

Current behavior

When isRoot() is accessed on a loaded root process, Process::$parentProcess must not be accessed before initialization is thrown.

While constructor initialization is correct, I think the problem is that Doctrine does not call constructor. And this nullable property remains uninitialized for root processes.

The quick fix is to add a default value: private ?self $parentProcess = null;

Originally created by @vudaltsov on GitHub (May 12, 2020). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.7.2 #### Summary part of an entity: ```php /** * @ORM\Entity() */ class Process { /** * @ORM\ManyToOne(targetEntity=Process::class) * @ORM\JoinColumn() */ private ?self $parentProcess; public function __construct(?self $parentProcess = null) { $this->parentProcess = $parentProcess; } private function isRoot(): bool { return null === $this->parentProcess; } } ``` #### Current behavior When `isRoot()` is accessed on a loaded **root** process, `Process::$parentProcess must not be accessed before initialization` is thrown. While constructor initialization is correct, I think the problem is that Doctrine does not call constructor. And this nullable property remains uninitialized for root processes. The quick fix is to add a default value: `private ?self $parentProcess = null;`
Author
Owner

@SenseException commented on GitHub (May 13, 2020):

I assume a null value doesn't get hydrated, because it wasn't necessary for the ORM to do this in the past.

@SenseException commented on GitHub (May 13, 2020): I assume a null value doesn't get hydrated, because it wasn't necessary for the ORM to do this in the past.
Author
Owner

@vudaltsov commented on GitHub (May 13, 2020):

@SenseException , yes, exactly. I hope I can find some time to do a PR

@vudaltsov commented on GitHub (May 13, 2020): @SenseException , yes, exactly. I hope I can find some time to do a PR
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6464