mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Exception when deleting entity with readonly ID property in model (PHP 8.1 feature) #7035
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @mrcage on GitHub (Sep 7, 2022).
Bug Report
Summary
When I try to remove an entity with a model which as a readonly ID property through the entity manager, an exception is thrown. I am using PHP 8.1 which added support for readonly properties, and this is supported since ORM 2.11 according to the release notes.
I am using Slim 4 as a framework.
Current behavior
The following exception is thrown when trying to call the delete method on my entity repository class:
Type: LogicException
Code: 0
Message: Attempting to change readonly property App\Models\Text::$id.
File: C:...\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ReflectionReadonlyProperty.php
Trace:
How to reproduce
My model:
My Repository:
SQL used to create the relevant database table:
Expected behavior
No exception should be thrown.
@Nayte91 commented on GitHub (Oct 2, 2022):
I confirm this issue, I experience the same problem on my home project and on a synthetic test project, typically the base demo for API Platform; With an enhanced readonly $id on a given Entity, you can get, post, put, but no delete.
Note that is the same problem with:
public readonly ?int $id;and:
public readonly int $id;Problem is that this exact example is given in the Doctrine's blog post, so it's kind of a flagship feature.
Hope it can help,
@Nayte91 commented on GitHub (Oct 4, 2022):
The LogicException is thrown by ORM/Mapping/ReflectionReadonlyProperty::setValue()L46;
It seems that the condition tests if parent::getValue($objectOrValue), that returns our readonly property value (in our examples, our Entity's readonly $id), is different from $value, that is a parameter of the public function setValue(mixed $objectOrValue, mixed $value = null): void.
The setValue() method is called by ORM\UnitOfWork::executeDeletions()L1256, with a $value = null;
I wonder it should try to make such a move when a property is readonly, by wanting to set a value. Or if ReflectionReadonlyProperty::setValue() act like it should. Either UnitOfWork::executeDeletions() should test if we face a ReflectionReadonlyProperty before asking to set a value, or ReflectionReadonlyProperty::setValue() shouldn't change the value tell it's ok (but this is lying and lying is bad so I'm not fond of this one).
I don't really understand the strategy around UnitOfWork::executeDeletions() that transforms entities into "new ones" by setting ids to null:
So I can't take a decision about what to do here to fix.