| Q | A
|------------ | ------
| BC Break | no
| Version | 2.6.4
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.
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
$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;
}
}
md5-c16e00f7d8e79945fc87e0b36f4fbcf9
```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>
The entity should be fetched from the database and hydrated.
@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 Added the testcase, can I be of any further assistance on this issue?
@sspat Do you like to add a fix for the failing test?
@SenseException Could you explain please, what did you mean? The test failing on <=7.3, or the fix for the bug itself? Thanks
@lcobucci @SenseException moved the test entity to a separate file, all tests passing now on <=7.3
The fix of the bug itself. :-) Thank you for your work.
Any updates on this issue?
Updates can be found in the corresponding PR #7857.
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.
Per https://github.com/doctrine/orm/pull/7857#issuecomment-575537801, I believe this is fixed in doctrine/persistence.
Most helpful comment
Any updates on this issue?