Skip to content

Conversation

SherinBloemendaal
Copy link

UnitOfWork was incorrectly detecting changes for database-generated columns with insertable: false and updatable: false, causing entities to be scheduled for update when only generated values changed.

This adds checks to skip notInsertable fields for NEW entities and notUpdatable fields for MANAGED entities during change detection, aligning UnitOfWork behavior with BasicEntityPersister.

Fixes #12017


foreach ($actualData as $propName => $actualValue) {
if (! isset($class->associationMappings[$propName])) {
if (isset($class->fieldMappings[$propName]->notInsertable)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checking for isset does not make sense. Both true and false boolean values will be considered set.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds logic to me. Will change it.

I followed the style of the BasicEntityPersister but I think the same issue is over there:

if ($isInsert && isset($fieldMapping->notInsertable)) {
continue;
}

I think its working right now because the actual type seems to be null|true instead of null|bool looking at:
Its only set, if the flag is false.

if (! $flag) {
$this->mapping['notInsertable'] = true;
}

Shall I patch it in this PR or create a new one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

joy of using confusing types like null|true instead of bool for a boolean use case...

Based on the existing type, the code with isset is correct then.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I completely agree. I've already changed it, but would you prefer I revert it back to isset?
Alternatively, I can create a new draft PR, since the type is defined as bool|null and this could help prevent confusion like this in the future.

type: 'datetime_immutable',
insertable: false,
updatable: false,
columnDefinition: 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this column definition is not portable across platforms, while your test is not restricted to some platforms.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Fixed!

UnitOfWork was incorrectly detecting changes for database-generated
columns with insertable: false and updatable: false, causing entities
to be scheduled for update when only generated values changed.

This adds checks to skip notInsertable fields for NEW entities and
notUpdatable fields for MANAGED entities during change detection,
aligning UnitOfWork behavior with BasicEntityPersister.

Fixes doctrine#12017
@SherinBloemendaal SherinBloemendaal force-pushed the fix-generated-fields-changeset-detection branch from 3a0fb22 to 860a64c Compare June 27, 2025 13:20
@greg0ire greg0ire deleted the branch doctrine:3.4.x July 4, 2025 06:10
@greg0ire greg0ire closed this Jul 4, 2025
@greg0ire
Copy link
Member

greg0ire commented Jul 4, 2025

Can you please retarget on 3.5.x? This got closed because I deleted 3.4.x

@SherinBloemendaal
Copy link
Author

Yes will do that within a few days. Thanks!

@SherinBloemendaal
Copy link
Author

I apologize for the delay.

I have retargeted it on 3.6.x because 3.5.x has been released. I don't know if this is considered a BC but I can retarget on 3.5.x also. (See #12171)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generated columns with insertable/updatable=false cause false positive change detection

3 participants