-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Bug report
When Doctrine ORM second-level cache is enabled, entities containing JoliCode\MediaBundle\Model\Media can be read from cache with a broken Media object state.
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html
I consistently get:
- deprecations about dynamic properties
Media::$0andMedia::$1during unserialization - then a fatal error when accessing
Media::getPath():Typed property JoliCode\MediaBundle\Model\Media::$path must not be accessed before initialization
This looks related to Media::__serialize() returning a positional array while Media has no matching __unserialize() to restore typed/readonly constructor properties.
Environment
- PHP: 8.2.16
- Symfony Framework Bundle: 7.4.5
- Doctrine ORM: 3.6.2
- DoctrineBundle: 2.18.2
- symfony/cache: 7.4.5
- jolicode/media-bundle: v0.2.1 (
2b3ef65638d5de23c94bdd811d308ef5d5539056)
Doctrine second-level cache setup
config/packages/doctrine.yaml:
doctrine:
orm:
second_level_cache:
enabled: true
log_enabled: true
region_cache_driver:
type: pool
pool: doctrine.second_level_cache_pool
region_lifetime: 3600Entities using SLC:
Service(#[ORM\Cache(..., region: 'entity.service')])- related collections (
children,sections,faqs,galleryImages)
Service and ServiceGalleryImage both contain Media properties mapped with MediaTypes::MEDIA_LONG.
Reproduction
- Enable Doctrine second-level cache.
- Have an entity with a
Mediafield (JoliCode\MediaBundle\Model\Media) and cache it with#[ORM\Cache]. - Hit a page once (cache put).
- Hit the same page again (cache hit).
- Access
media.pathin Twig (or callgetPath()in PHP).
Expected result
Cached entities should hydrate with valid Media objects, and getPath() should work.
Actual result
Deprecations from cache unmarshalling
var/log/prod.deprecations-2026-02-12.log:
Deprecated: Creation of dynamic property JoliCode\MediaBundle\Model\Media::$0 is deprecated
... file: /var/www/vendor/symfony/cache/Marshaller/DefaultMarshaller.php:72
Deprecated: Creation of dynamic property JoliCode\MediaBundle\Model\Media::$1 is deprecated
... file: /var/www/vendor/symfony/cache/Marshaller/DefaultMarshaller.php:72
Fatal error later when reading media path
var/log/prod-2026-02-12.log:
Uncaught PHP Exception Twig\Error\RuntimeError:
"An exception has been thrown during the rendering of a template
("Typed property JoliCode\MediaBundle\Model\Media::$path must not be accessed before initialization")
in "components/ServiceCard.html.twig" at line 95."
previous:
Error: Typed property JoliCode\MediaBundle\Model\Media::$path must not be accessed before initialization
at /var/www/vendor/jolicode/media-bundle/src/Model/Media.php:151
SLC statistics confirm cache hits
var/log/slc_prod-2026-02-12.log:
"delta":{"total":{"hit":4,"miss":0,"put":0}, ... "entity.service":{"hit":3,"miss":0,"put":0}, ...}
So the issue appears on reads from second-level cache.
Additional observation
In vendor/jolicode/media-bundle/src/Model/Media.php, I see:
public function __serialize(): array
{
return [$this->path, $this->storage->getLibrary()->getName()];
}But I do not see a corresponding __unserialize() implementation to restore object state ($path, $storage, etc.).
Could this be the root cause for cache-unserialized Media objects ending up partially initialized?
Thank you in advance