Skip to content

"LogicException: Attempting to change readonly property ..." for entity's Id during proxy initialization #9863

@Firehed

Description

@Firehed

Bug Report

Q A
BC Break no
Version 2.12.3

Summary

When initializing a proxy by accessing a non-loaded property, if the Id is set as readonly, a LogicException gets thrown.

Probably similar to #9538, but in a different code path. I ran into this by directly using getReference(), but I suspect the behavior would be exhibited on any proxy relation.

Current behavior

LogicException: Attempting to change readonly property Firehed\Entities\Feed::$id. in /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionReadonlyProperty.php:48

Stack:

reader-php_fpm-1    | #0 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(2745): Doctrine\ORM\Mapping\ReflectionReadonlyProperty->setValue(Object(DoctrineProxies\__CG__\Firehed\Entities\Feed), '2')
reader-php_fpm-1    | #1 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php(156): Doctrine\ORM\UnitOfWork->createEntity('Firehed\\Entitie...', Array, Array)
reader-php_fpm-1    | #2 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php(63): Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateRowData(Array, Array)
reader-php_fpm-1    | #3 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php(270): Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator->hydrateAllData()
reader-php_fpm-1    | #4 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(757): Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll(Object(Doctrine\DBAL\Result), Object(Doctrine\ORM\Query\ResultSetMapping), Array)
reader-php_fpm-1    | #5 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(767): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->load(Array, Object(DoctrineProxies\__CG__\Firehed\Entities\Feed))
reader-php_fpm-1    | #6 /var/www/html/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php(132): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->loadById(Array, Object(DoctrineProxies\__CG__\Firehed\Entities\Feed))
reader-php_fpm-1    | #7 /var/www/html/.generated/doctrine-proxies/__CG__FirehedEntitiesFeed.php(75): Doctrine\ORM\Proxy\ProxyFactory->Doctrine\ORM\Proxy\{closure}(Object(DoctrineProxies\__CG__\Firehed\Entities\Feed), '__get', Array)
reader-php_fpm-1    | #8 /var/www/html/.generated/doctrine-proxies/__CG__FirehedEntitiesFeed.php(75): Closure->__invoke(Object(DoctrineProxies\__CG__\Firehed\Entities\Feed), '__get', Array)
reader-php_fpm-1    | #9 /var/www/html/src/Api/MyStories.php(47): DoctrineProxies\__CG__\Firehed\Entities\Feed->__get('title')
reader-php_fpm-1    | #10 /var/www/html/public/index.php(71): Firehed\Api\MyStories->run(Array)
reader-php_fpm-1    | #11 {main}

How to reproduce

Entity:

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping\{
    Column,
    Entity,
    GeneratedValue,
    Id,
    Table,
};

#[Entity]
#[Table(name: 'feeds')]
class Feed
{
    #[Id]
    #[GeneratedValue]
    #[Column(options: ['unsigned' => true], type: Types::BIGINT)]
    public readonly int $id;

    #[Column(options: ['default' => ''])]
    public string $title;
}

Table:

CREATE TABLE `feeds` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Code to cause error:

$reference = $em->getReference(Feed::class, 2);
var_dump($reference->id); // int(2)
var_dump($reference->title); // <-- crash here

Expected behavior

Data is loaded fine, var_dump shows the expected value from the db.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions