Search code examples
phpsymfonydoctrine-ormdoctrinesecond-level-cache

Doctrine's Second Level Cache doesn't show new items


I'm using Symfony 6.2.12 with Doctrine 2.15.3 and try to implement the second level cache. The profiler bar shows the expected cache hits, so that is working. The problem appears, however, when I add new items to the cached entity (using the EntityManager). The cache doesn't seem to be aware of the new items and findBy() still returns the old array before I added them. Note that I don't modify any existing entities, the list should just have more items.

my doctrine.yaml:

doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
    orm:
        auto_generate_proxy_classes: true
        naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App
        second_level_cache:
            enabled: true
            regions:
                append_only:
                    lifetime: 8640000
                    cache_driver:
                        type: service
                        id: cache.app

I chose READ_ONLY for the entity because existing entries never change. (I tested also with NONSTRICT_READ_WRITE and READ_WRITE, but without improvement.) When I remove that ORM\Cache attribute, the new items naturally appear in the list, so it is definitely an issue with the cache.

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: LogRepository::class)]
#[ORM\Cache(usage: "READ_ONLY", region: "append_only")]
class Log
{

In the controller I retrieve the array of items from the LogRepository (the default one, extending from ServiceEntityRepository):

$logs = $logRepository->findBy(
    $criteria,
    ['id' => 'DESC'],
    $limit,
    $offset
);

Is that a configuration problem?

Of course I can evict the entire cache region whenever I add a new item, then the list is up-to-date:

/** @var \Doctrine\ORM\Cache $cache */
$cache = $this->entityManager->getCache();
$cache->evictEntityRegion(Log::class);

But that's not how I understand the READ_ONLY cache where you should be able to append items to the cached region.


Solution

  • It works now with some modifications:

    doctrine.yaml

    doctrine:
        dbal:
            url: '%env(resolve:DATABASE_URL)%'
        orm:
            auto_generate_proxy_classes: true
            naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
            auto_mapping: true
            mappings:
                App:
                    is_bundle: false
                    dir: '%kernel.project_dir%/src/Entity'
                    prefix: 'App\Entity'
                    alias: App
            second_level_cache:
                enabled: true
                
                region_cache_driver:
                    type: service
                    id: cache.app
                regions:
                    append_only:
                        lifetime: 8640000
    

    and for the entity

    #[ORM\Cache(usage: "NONSTRICT_READ_WRITE", region: "append_only")]
    

    with NONSTRICT_READ_WRITE instead of READ_ONLY.