[3.4.0, PHP <8.4] Cannot hydrate readonly properties from superclass of embeddable #7518

Open
opened 2026-01-22 15:52:49 +01:00 by admin · 7 comments
Owner

Originally created by @udavka on GitHub (Jun 15, 2025).

Bug Report

Q A
Version 3.4.0
PHP version <8.4.0

Summary

For embeddables that have superclasses, the hydrator cannot set readonly properties that are inherited from a superclass (for PHP <8.4).

Current behavior

Inherited readonly properties cannot be set and an exception is thrown: Error: Cannot initialize readonly property <super-class>::$<prop-name> from scope <derived-class>. The entity hydration is terminated.
The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore.

Expected behavior

The hydration is successful.

How to reproduce

Just use an embeddable with a superclass that has a readonly ORM column.

Originally created by @udavka on GitHub (Jun 15, 2025). ### Bug Report | Q | A |-------------------------------------------- | ------ | Version | 3.4.0 | PHP version | <8.4.0 #### Summary For embeddables that have superclasses, the hydrator cannot set readonly properties that are inherited from a superclass (for PHP <8.4). #### Current behavior Inherited readonly properties cannot be set and an exception is thrown: `Error: Cannot initialize readonly property <super-class>::$<prop-name> from scope <derived-class>`. The entity hydration is terminated. The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore. #### Expected behavior The hydration is successful. #### How to reproduce Just use an embeddable with a superclass that has a readonly ORM column.
Author
Owner

@greg0ire commented on GitHub (Jun 16, 2025):

Can you please provide a stack trace?

@greg0ire commented on GitHub (Jun 16, 2025): Can you please provide a [stack trace](https://symfony.com/doc/current/contributing/code/stack_trace.html#getting-stack-traces-with-symfony)?
Author
Owner

@udavka commented on GitHub (Jun 16, 2025):

Error: Cannot initialize readonly property <super-class>::$<prop-name> from scope <derived-class>

vendor/doctrine/orm/src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php:40
vendor/doctrine/orm/src/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessor.php:57
vendor/doctrine/orm/src/Mapping/PropertyAccessors/ReadonlyAccessor.php:30
vendor/doctrine/orm/src/Mapping/PropertyAccessors/EmbeddablePropertyAccessor.php:35
vendor/doctrine/orm/src/UnitOfWork.php:2411
vendor/doctrine/orm/src/Internal/Hydration/SimpleObjectHydrator.php:176
vendor/doctrine/orm/src/Internal/Hydration/SimpleObjectHydrator.php:60
vendor/doctrine/orm/src/Internal/Hydration/AbstractHydrator.php:171
vendor/doctrine/orm/src/Persisters/Entity/BasicEntityPersister.php:754
vendor/doctrine/orm/src/EntityRepository.php:125
custom code: EntityRepository::findOneBy(...)
@udavka commented on GitHub (Jun 16, 2025): Error: Cannot initialize readonly property `<super-class>::$<prop-name>` from scope `<derived-class>` ``` vendor/doctrine/orm/src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php:40 vendor/doctrine/orm/src/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessor.php:57 vendor/doctrine/orm/src/Mapping/PropertyAccessors/ReadonlyAccessor.php:30 vendor/doctrine/orm/src/Mapping/PropertyAccessors/EmbeddablePropertyAccessor.php:35 vendor/doctrine/orm/src/UnitOfWork.php:2411 vendor/doctrine/orm/src/Internal/Hydration/SimpleObjectHydrator.php:176 vendor/doctrine/orm/src/Internal/Hydration/SimpleObjectHydrator.php:60 vendor/doctrine/orm/src/Internal/Hydration/AbstractHydrator.php:171 vendor/doctrine/orm/src/Persisters/Entity/BasicEntityPersister.php:754 vendor/doctrine/orm/src/EntityRepository.php:125 custom code: EntityRepository::findOneBy(...) ```
Author
Owner

@beberlei commented on GitHub (Jun 22, 2025):

@udavka did this work in 3.3?

@beberlei commented on GitHub (Jun 22, 2025): @udavka did this work in 3.3?
Author
Owner

@udavka commented on GitHub (Jun 22, 2025):

@udavka did this work in 3.3?

Yes, that's why I wrote: The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore.

@udavka commented on GitHub (Jun 22, 2025): > [@udavka](https://github.com/udavka) did this work in 3.3? Yes, that's why I wrote: _The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore._
Author
Owner

@beberlei commented on GitHub (Jun 22, 2025):

Yes, that's why I wrote: The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore.

Oh, overread that. Thanks

@beberlei commented on GitHub (Jun 22, 2025): > Yes, that's why I wrote: _The problem is introduced in 3.4.0 with new property accessors. The previous reflection property-based code still works, but it is not used in the hydration code anymore._ Oh, overread that. Thanks
Author
Owner

@udavka commented on GitHub (Jun 22, 2025):

I have finally found how to fix it.

This line:
src/Mapping/ClassMetadata.php:857 must be not

$accessor = PropertyAccessorFactory::createPropertyAccessor($mapping->originalClass, $mapping->originalField);

but

$accessor = PropertyAccessorFactory::createPropertyAccessor($mapping->declared ?? $mapping->originalClass, $mapping->originalField);

I'm sorry, I have no idea how to create a proper pull request. Anyway, I hope that this can help.

@udavka commented on GitHub (Jun 22, 2025): I have finally found how to fix it. This line: [src/Mapping/ClassMetadata.php:857](https://github.com/doctrine/orm/blob/3.4.x/src/Mapping/ClassMetadata.php#L857) must be not ``` php $accessor = PropertyAccessorFactory::createPropertyAccessor($mapping->originalClass, $mapping->originalField); ``` but ``` php $accessor = PropertyAccessorFactory::createPropertyAccessor($mapping->declared ?? $mapping->originalClass, $mapping->originalField); ``` I'm sorry, I have no idea how to create a proper pull request. Anyway, I hope that this can help.
Author
Owner

@greg0ire commented on GitHub (Jun 22, 2025):

@udavka we have a guide, in case you want to give it a try.

@greg0ire commented on GitHub (Jun 22, 2025): @udavka we have [a guide](https://www.doctrine-project.org/contribute/index.html), in case you want to give it a try.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7518