Skip to content

readonly support for identifiers #353

@benblub

Description

@benblub

If you use readonly on the id/identifier an error is thrown. Use readonly on $title works as expected.

if we take a look into the code where the error is thrown..
if we look into the comparison, values are the same, so the object instance is not the same

        if (parent::getValue($objectOrValue) !== $value) {
            throw new LogicException(sprintf('Attempting to change readonly property %s::$%s.', $this->class, $this->name));
        }

Stacktrace

LogicException : Attempting to change readonly property App\Foo\Domain\Model\Foo::$id.
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ReflectionReadonlyProperty.php:48
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2753
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:266
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:492
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php:148
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:270
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php:841
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2227
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:2199
 /app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:711
 /app/vendor/zenstruck/foundry/src/Proxy.php:168
 /app/vendor/zenstruck/foundry/src/Proxy.php:131

Model/Entity

#[ORM\Entity]
class Foo
{
    #[ORM\Id]
    #[ORM\Column(type: 'uuid', unique: true)]
    public readonly UuidInterface $id;

    public function __construct(
        #[ORM\Embedded(columnPrefix: false)]
        public readonly Title $title,
    ) {
        $this->id = Uuid::uuid4();
    }
}

Factory

    protected function getDefaults(): array
    {
        return [
            'title' => new Title('Foo..'),
        ];
    }

    protected function initialize(): self
    {
        return $this->instantiateWith((new Instantiator())->alwaysForceProperties());
    }

i didn't looked yet deep dive into the code how foundry instantiate the object and whats the different there between normal props and the identifier. With PHP 8.2 we get immutable classes, this examble used readonly probs -> PHP 8.1

https://stitcher.io/blog/php-81-readonly-properties

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