Hydration not working for Embeddables with php 7.4 typed properties #6324

Closed
opened 2026-01-22 15:30:56 +01:00 by admin · 10 comments
Owner

Originally created by @sspat on GitHub (Oct 7, 2019).

Bug Report

Q A
BC Break no
Version 2.6.4

Summary

There is an error when using php 7.4 and trying to fetch an entity from the database that has typed properties containing value objects that are mapped as embeddables.

Current behavior

There is a fatal error.

Fatal error: Uncaught Error: Typed property App\Domain\Entity\City\City::$id must not be accessed before initialization in /var/www/vendor/doctrine/or
m/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php:89
Stack trace:
#0 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php(89): ReflectionProperty->getValue(Object(App\Domain\Entity\Cit
y\City))
#1 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(2670): Doctrine\ORM\Mapping\ReflectionEmbeddedProperty->setValue(Object(App\Domain\Ent
ity\City\City), '29df4356-b832-4...')
#2 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(271): Doctrine\ORM\UnitOfWork->createEntity('App\\Domain\\Enti.
..', Array, Array)
#3 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(492): Doctrine\ORM\Internal\Hydration\ObjectHydrator->getEntity
(Array, 'c')
#4 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(162): Doctrine\ORM\Internal\Hydration\ObjectHyd in /var/www/ven
dor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php on line 89

How to reproduce

$this
            ->entityManager
            ->createQueryBuilder()
            ->select('c')
            ->from(City::class, 'c')
            ->where('c.id.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->getOneOrNullResult();
<?php
namespace App\Domain\Entity\City;
use App\Domain\Entity\City\ValueObject\CityId;

class City
{
    private CityId $id;
}
<?php
namespace App\Domain\Entity\City\ValueObject;

final class CityId
{
    private string $id;

    private function __construct(string $id)
    {
        $this->id = $id;
    }
}
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name="App\Domain\Entity\City\City" table="city">
        <embedded name="id" class="App\Domain\Entity\City\ValueObject\CityId" use-column-prefix="false" />
</doctrine-mapping>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <embeddable name="App\Domain\Entity\City\ValueObject\CityId">
        <id name="id" type="guid" column="id">
            <generator strategy="NONE" />
        </id>
    </embeddable>
</doctrine-mapping>

Expected behavior

The entity should be fetched from the database and hydrated.

Originally created by @sspat on GitHub (Oct 7, 2019). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.6.4 #### Summary There is an error when using php 7.4 and trying to fetch an entity from the database that has typed properties containing value objects that are mapped as embeddables. #### Current behavior There is a fatal error. ``` Fatal error: Uncaught Error: Typed property App\Domain\Entity\City\City::$id must not be accessed before initialization in /var/www/vendor/doctrine/or m/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php:89 Stack trace: #0 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php(89): ReflectionProperty->getValue(Object(App\Domain\Entity\Cit y\City)) #1 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(2670): Doctrine\ORM\Mapping\ReflectionEmbeddedProperty->setValue(Object(App\Domain\Ent ity\City\City), '29df4356-b832-4...') #2 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(271): Doctrine\ORM\UnitOfWork->createEntity('App\\Domain\\Enti. ..', Array, Array) #3 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(492): Doctrine\ORM\Internal\Hydration\ObjectHydrator->getEntity (Array, 'c') #4 /var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php(162): Doctrine\ORM\Internal\Hydration\ObjectHyd in /var/www/ven dor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php on line 89 ``` #### How to reproduce ```php $this ->entityManager ->createQueryBuilder() ->select('c') ->from(City::class, 'c') ->where('c.id.id = :id') ->setParameter('id', $id) ->getQuery() ->getOneOrNullResult(); ``` ```php <?php namespace App\Domain\Entity\City; use App\Domain\Entity\City\ValueObject\CityId; class City { private CityId $id; } ``` ```php <?php namespace App\Domain\Entity\City\ValueObject; final class CityId { private string $id; private function __construct(string $id) { $this->id = $id; } } ``` ```xml <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="App\Domain\Entity\City\City" table="city"> <embedded name="id" class="App\Domain\Entity\City\ValueObject\CityId" use-column-prefix="false" /> </doctrine-mapping> ``` ```xml <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <embeddable name="App\Domain\Entity\City\ValueObject\CityId"> <id name="id" type="guid" column="id"> <generator strategy="NONE" /> </id> </embeddable> </doctrine-mapping> ``` #### Expected behavior The entity should be fetched from the database and hydrated.
admin closed this issue 2026-01-22 15:30:56 +01:00
Author
Owner

@Ocramius commented on GitHub (Oct 8, 2019):

@sspat can you isolate this into a test case? I think we'll need to add overhead to ReflectionEmbeddedProperty so that it checks whether the property was initialized (new PHP 7.4 API)

@Ocramius commented on GitHub (Oct 8, 2019): @sspat can you isolate this into a test case? I think we'll need to add overhead to `ReflectionEmbeddedProperty` so that it checks whether the property was initialized (new PHP 7.4 API)
Author
Owner

@sspat commented on GitHub (Oct 8, 2019):

@Ocramius Added the testcase, can I be of any further assistance on this issue?

@sspat commented on GitHub (Oct 8, 2019): @Ocramius Added the testcase, can I be of any further assistance on this issue?
Author
Owner

@SenseException commented on GitHub (Oct 10, 2019):

@sspat Do you like to add a fix for the failing test?

@SenseException commented on GitHub (Oct 10, 2019): @sspat Do you like to add a fix for the failing test?
Author
Owner

@sspat commented on GitHub (Oct 10, 2019):

@SenseException Could you explain please, what did you mean? The test failing on <=7.3, or the fix for the bug itself? Thanks

@sspat commented on GitHub (Oct 10, 2019): @SenseException Could you explain please, what did you mean? The test failing on <=7.3, or the fix for the bug itself? Thanks
Author
Owner

@sspat commented on GitHub (Oct 14, 2019):

@lcobucci @SenseException moved the test entity to a separate file, all tests passing now on <=7.3

@sspat commented on GitHub (Oct 14, 2019): @lcobucci @SenseException moved the test entity to a separate file, all tests passing now on <=7.3
Author
Owner

@SenseException commented on GitHub (Oct 17, 2019):

The fix of the bug itself. :-) Thank you for your work.

@SenseException commented on GitHub (Oct 17, 2019): The fix of the bug itself. :-) Thank you for your work.
Author
Owner

@ansien commented on GitHub (Nov 29, 2019):

Any updates on this issue?

@ansien commented on GitHub (Nov 29, 2019): Any updates on this issue?
Author
Owner

@SenseException commented on GitHub (Dec 2, 2019):

Updates can be found in the corresponding PR #7857.

@SenseException commented on GitHub (Dec 2, 2019): Updates can be found in the corresponding PR #7857.
Author
Owner

@internalsystemerror commented on GitHub (Dec 18, 2019):

The solution "appears" to be simple. In ReflectionEmbeddedProperty.php change line 89:

$embeddedObject = $this->parentProperty->getValue($object);

to

$embeddedObject = $this->parentProperty->isInitialized($object) ? $this->parentProperty->getValue($object) : null;

I've tried to read as much of the open issues/PR/history on this matter and it appears that the solution will be to create a ReflectionEmbeddedProperty74 class which is used instead for PHP 7,4? Tests appear to be written in the PR mentioned above.

Am I missing anything? I'm happy to contribute or wait, whichever is required. Performance implications were implied however, I'm unable to find these.

@internalsystemerror commented on GitHub (Dec 18, 2019): The solution "appears" to be simple. In ReflectionEmbeddedProperty.php change line 89: ``` $embeddedObject = $this->parentProperty->getValue($object); ``` to ``` $embeddedObject = $this->parentProperty->isInitialized($object) ? $this->parentProperty->getValue($object) : null; ``` I've tried to read as much of the open issues/PR/history on this matter and it appears that the solution will be to create a ReflectionEmbeddedProperty74 class which is used instead for PHP 7,4? Tests appear to be written in the PR mentioned above. Am I missing anything? I'm happy to contribute or wait, whichever is required. Performance implications were implied however, I'm unable to find these.
Author
Owner

@shadowhand commented on GitHub (Jan 17, 2020):

Per https://github.com/doctrine/orm/pull/7857#issuecomment-575537801, I believe this is fixed in doctrine/persistence.

@shadowhand commented on GitHub (Jan 17, 2020): Per https://github.com/doctrine/orm/pull/7857#issuecomment-575537801, I believe this is fixed in `doctrine/persistence`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6324