Skip to content

Commit e800bf5

Browse files
committed
Skip writing readonly properties if the value did not change
1 parent 5b6f3aa commit e800bf5

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ class ClassMetadataInfo implements ClassMetadata
701701
/**
702702
* The ReflectionProperty instances of the mapped class.
703703
*
704-
* @var ReflectionProperty[]|null[]
704+
* @var array<string, ReflectionProperty|null>
705705
*/
706706
public $reflFields = [];
707707

lib/Doctrine/ORM/UnitOfWork.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
use Doctrine\Persistence\PropertyChangedListener;
4141
use Exception;
4242
use InvalidArgumentException;
43+
use LogicException;
4344
use RuntimeException;
4445
use Throwable;
4546
use UnexpectedValueException;
@@ -53,6 +54,7 @@
5354
use function array_pop;
5455
use function array_sum;
5556
use function array_values;
57+
use function assert;
5658
use function count;
5759
use function current;
5860
use function get_class;
@@ -66,6 +68,8 @@
6668
use function spl_object_id;
6769
use function sprintf;
6870

71+
use const PHP_VERSION_ID;
72+
6973
/**
7074
* The UnitOfWork is responsible for tracking changes to objects during an
7175
* "object-level" transaction and for writing out changes to the database
@@ -2724,9 +2728,25 @@ public function createEntity($className, array $data, &$hints = [])
27242728
}
27252729

27262730
foreach ($data as $field => $value) {
2727-
if (isset($class->fieldMappings[$field])) {
2728-
$class->reflFields[$field]->setValue($entity, $value);
2731+
if (! isset($class->fieldMappings[$field])) {
2732+
continue;
27292733
}
2734+
2735+
assert($class->reflFields[$field] !== null);
2736+
2737+
if (
2738+
PHP_VERSION_ID >= 80100
2739+
&& $class->reflFields[$field]->isReadOnly()
2740+
&& $class->reflFields[$field]->isInitialized($entity)
2741+
) {
2742+
if ($class->reflFields[$field]->getValue($entity) === $value) {
2743+
continue;
2744+
}
2745+
2746+
throw new LogicException(sprintf('Attempting to change readonly field %s.', $field));
2747+
}
2748+
2749+
$class->reflFields[$field]->setValue($entity, $value);
27302750
}
27312751

27322752
// Loading the entity right here, if its in the eager loading map get rid of it there.

phpstan-baseline.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,3 +1904,4 @@ parameters:
19041904
message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$subClasses\\.$#"
19051905
count: 1
19061906
path: lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php
1907+

psalm-baseline.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3559,7 +3559,7 @@
35593559
<code>$assoc['targetEntity']</code>
35603560
<code>$assoc['type']</code>
35613561
</PossiblyNullArrayAccess>
3562-
<PossiblyNullReference occurrences="33">
3562+
<PossiblyNullReference occurrences="32">
35633563
<code>buildCachedCollectionPersister</code>
35643564
<code>buildCachedEntityPersister</code>
35653565
<code>getCacheFactory</code>
@@ -3592,7 +3592,6 @@
35923592
<code>setValue</code>
35933593
<code>setValue</code>
35943594
<code>setValue</code>
3595-
<code>setValue</code>
35963595
</PossiblyNullReference>
35973596
<PossiblyUndefinedMethod occurrences="4">
35983597
<code>addPropertyChangedListener</code>

0 commit comments

Comments
 (0)