doctrinelockingapi-platform.comsecond-level-cache

ApiPlatform/Doctrine - Unable to use Second Level Cache with error "Unable to use access strategy type of [3] without a ConcurrentRegion"


My environment is:

api-platform: v3.0.0
symfony: 6.1.0
doctrine\cache: 2.2
doctrine\orm: 2.13.1

I am trying to set up a second level cache region with READ_WRITE access. Per specification READ_WRITE usage requires the use of a ConcurrentRegion due to the cache being locked as long as it is written or read.

I've created a cache pool to use on the second level cache:

### config/packages/cache.yaml
framework:
    cache:
        app: cache.adapter.redis
        default_redis_provider: '%env(REDIS_URL)%'
        pools:
            doctrine.second_level_cache:
                adapter: cache.adapter.redis
                default_lifetime: 3600

The second level cache is configured as follows:

### config/packages/doctrine.yaml
doctrine:
    orm:
        second_level_cache:
            enabled: true
            region_cache_driver:
                type: pool
                pool: doctrine.second_level_cache # referenced in cache.yaml

            regions:
                locked_region:
                    cache_driver:
                        type: pool
                        pool: doctrine.second_level_cache # referenced in cache.yaml
                    lock_path: '%kernel.cache_dir%/doctrine/orm/lock'

I am using the default doctrine UserProvider loading the User-Entity upon authentication. In order to use the Cache-Region with the User-Entity the Cache-Attribute is added:

### App\Entity\User.php

use Doctrine\ORM\Mapping\Cache;

#[Cache("READ_WRITE", "locked_region")]
class User implements UserInterface, PasswordAuthenticatedUserInterface, EquatableInterface
{

Now upon login (executing a POST) an InvalidArgumentException is thrown in vendor/doctrine/orm/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php (line 136) with the message Unable to use access strategy type of [3] without a ConcurrentRegion.

Doctrine is refusing to use the existing cache region because it expects a ConcurrentRegion (required on READ_WRITE) but receives a DefaultRegion. I am pretty sure my .yaml configuration is faulty...is the lock_path supposed to be a file-path - even when using Redis?

Thanks!


Solution

  • The fault lies in the configuration - the type property was missing.

    This works:

    ### config/packages/doctrine.yaml
    
    doctrine:
        second_level_cache:
            enabled: true
            regions:
                locked_region:
                    cache_driver:
                        type: pool
                        pool: doctrine.second_level_cache
                    type: filelock # <-- this one was missing
                    lock_path: '%kernel.cache_dir%/doctrine/orm/lock'