-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Open
Description
Bug Report
| Q | A |
|---|---|
| Version | 3.4.x |
| Previous Version if the bug is a regression | N/A |
Summary
Doctrine's UnitOfWork incorrectly detects changes for database-generated columns marked with insertable: false and updatable: false. This causes entities to be scheduled for update even though no actual changes have occurred, which can trigger unwanted events and break change tracking logic.
Current behavior
When an entity has database-generated columns (e.g., GENERATED ALWAYS AS columns) marked with both insertable: false and updatable: false, the UnitOfWork still includes these fields in change detection. This results in:
- Entities being incorrectly marked as "dirty" and added to
$entityUpdates getEntityChangeSet()returning phantom changes like['generatedField' => [null, DateTimeImmutable]]isScheduledForUpdate()returningtruewhen only generated fields have changedpreUpdateevents being triggered unnecessarily
Expected behavior
- Fields marked with
insertable: falseshould not appear in changesets for new entities during INSERT operations - Fields marked with
updatable: falseshould not appear in changesets for existing entities during UPDATE operations - Entities with only generated field "changes" should not be scheduled for update
- The UnitOfWork behavior should be consistent with BasicEntityPersister, which already skips these fields
How to reproduce
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'entity_with_generated_fields')]
class EntityWithGeneratedFields
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
public ?int $id = null;
#[ORM\Column(type: 'string')]
public ?string $name = null;
#[ORM\Column(
name: 'generated_field',
type: 'datetime_immutable',
insertable: false,
updatable: false,
columnDefinition: 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP',
generated: 'ALWAYS'
)]
public ?\DateTimeImmutable $generatedField = null;
}
$entity = new EntityWithGeneratedFields();
$entity->name = 'Test Entity';
$em->persist($entity);
$em->flush();
$entity->generatedField = new \DateTimeImmutable();
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
// Bug: Entity is incorrectly marked as having changes
assert($uow->isScheduledForUpdate($entity) === false); // Fails - returns true
assert($uow->getEntityChangeSet($entity) === []); // Fails - contains generated fieldThe issue occurs in UnitOfWork::computeChangeSet() and UnitOfWork::recomputeSingleEntityChangeSet() which don't check the notInsertable and notUpdatable field mapping properties during change detection.
Metadata
Metadata
Assignees
Labels
No labels