Bug #95899
openTry to cache an extbase queryResult leads to "Serialization of 'Closure' is not allowed"
0%
Description
I would like to add some caching into my backend views in lux to speed up diagrams.
But in TYPO3 11.5.2 together (with PHP 7.4 or 8.0) I always ran into the exception:
"Serialization of 'Closure' is not allowed"
An example extbase model could be very simple (without any relations or Lazy Loading) with just one string property and extend AbstractEntity. Also the repository function is without magic here:
$query = $this->createQuery(); $query->setLimit(3); $query->setOrderings(['uid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING]); return $query->execute();
If I try to cache the result like
$cacheInstance = GeneralUtility::makeInstance(CacheManager::class)->getCache('bar'); $cacheInstance->set('foo', $queryResult, ['bar'], 100000);
The error is happening:
Any ideas?
Files
Updated by Alex Kellner about 3 years ago
Update: Using an array instead of QueryResult helps as workarround:
$query->execute()->toArray();
Updated by Benni Mack almost 2 years ago
- Related to Bug #91364: Extbase/CachingFramework - Serialization on 'Closure' is not allowed added
Updated by Marvin Buchmann almost 2 years ago
- File File.php File.php added
- File SerializableEntityInterface.php SerializableEntityInterface.php added
- File SerializableEntityTrait.php SerializableEntityTrait.php added
Alex Kellner wrote in #note-1:
Update: Using an array instead of QueryResult helps as workaround:
[...]
Thanks! I had the same problem when trying to cache my QueryResult. But the workaround only seems to work if the model doesn't contain any (lazy) ObjectStorage properties (tested in TYPO3 11.5).
Since I needed those, I created a workaround that works for all my models. I got the idea from this fix https://review.typo3.org/c/Packages/TYPO3.CMS/+/68341.
It's basically just an interface and a trait unsetting all ObjectStorage properties by default when serialized and calling the initializeObject method of the object when unserialized. If not implemented, it provides one that just initializes the ObjectStorage properties empty.
The model has to implement the interface and use the trait. Then it's serializable and therefore cacheable. :) At least in my use cases.
I attached an example model, the interface and the trait.
I know traits are not really desirable, but the methods could be implemented in the AbstractEntity class if it works for all other use cases aswell. Then every extbase model would be cacheable by default, which I would really appreciate.