How to use Doctrine Result Cache [Symfony]

This is an article about Symfony and Doctrine.
Each version of this article is below.
Symfony 3.4
Doctrine 2.12

It is a memorandum because I reviewed the cache area again in the case of using the EC site framework called EC-CUBE.
The origin is that when deleting the cache in Doctrine 1.x, I used deleteByPrefix to delete by prefix match.But now deleteByPrefix is UNDEFIND.
The changes around the cache are summarized below.

## Cache Changes
  
- Renamed old AbstractCache to CacheProvider

- Dropped the support to the following functions of all cache providers:
  - CacheProvider::deleteByWildcard
  - CacheProvider::deleteByRegEx
  - CacheProvider::deleteByPrefix
  - CacheProvider::deleteBySuffix

- CacheProvider::deleteAll will not remove ALL entries, it will only mark them as invalid
- CacheProvider::flushAll will remove ALL entries, namespaced or not
- Added support to MemcachedCache
- Added support to WincacheCache

The function deleteByXXX has disappeared across the board.
When using Result Cache, it seems that the ID managed by prefixing cannot be used.
Well, instead of managing IDs, you should manage Cache properly with namespace.
You can clear the cache (deleteAll) for each namespace.
This time, I would like to explain how to use Result Cache. See below for information on other caches.
Official(English)::doctrine-project — Caching

Configure Symfony to use ResultCache

First of all, it is a setting. The reference is below.
Official::Configuration Reference — Cache Driver
Github::symfony / demo
You can customize it in various ways, but as a sample, I will use the one from Github as it is.

doctrine:
    orm:
        auto_generate_proxy_classes: false
        metadata_cache_driver:
            type: pool
            pool: doctrine.system_cache_pool
        query_cache_driver:
            type: pool
            pool: doctrine.system_cache_pool
        result_cache_driver:
            type: pool
            pool: doctrine.result_cache_pool

framework:
    cache:
        pools:
            doctrine.result_cache_pool:
                adapter: cache.app
            doctrine.system_cache_pool:
                adapter: cache.system

If you write the above in doctrine.yaml, the setting is completed.

Use Result Cache

Result Cache can cache the result of DQL query. Related methods are available by creating a DQL query.

// Case Repository (extends ServiceEntityRepository)

$qb = $this->createQueryBuilder('user')
    ->where('user.id = :id')
    ->setParameter('id', $userId);    
$qb->getQuery()
    ->useResultCache(true, 600, 'UserInfo')
    ->getResult();

After the DQL query is created with getQuery(), the related methods will be available.
I am using useResultCache to store in ResultCache.
There are three arguments, but each explanation is below.

[1] Cache driver
TRUE: use default cache driver
FALSE: Do not use cache
Cache driver specification
[2] Cache lifetime
Default value of the driver if omitted
[3] ID
If omitted, the MD5 hash value is automatically generated

See below for other methods.
https://doctrine2.readthedocs.io/en/latest/reference/caching.html
This time, I haven’t specified namespace yet, so a cache without namespace will be created.
For example, deleteAll without specifying namespace will delete all caches that do not have a namespace.

Delete Result Cache

How to delete ResultCache. There are delete($id) and deleteAll.
Call the driver from DQL query to remove it.

// Case Repository (extends ServiceEntityRepository)

$qb = $this->getEntityManager()->createQuery();

$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->delete('UserInfo');

In the above example, the cache with ID UserInfo will be deleted. It’s easy.

Now, next is my theme this time, when I want to delete only a specific cache at once.
In the case of doctrine1.x, the ID was prefixed and deleted with deleteByPrefix() as a prefix match.
That method is no longer available, so manage the cache with namespace.

Manage resultCache using namespace

Simply put, you just create a box called namespace. We will store the cache there.
This is convenient when you have multiple projects or want to separate the cache for User, the cache for Admin, etc.
Here is a simple sample.

// Case Repository (extends ServiceEntityRepository)

// use ResultCashe in namespace "User"
$qb = $this->createQueryBuilder('user')
    ->where('user.id = :id')
    ->setParameter('id', $userId)
    ->getQuery();

$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');

$result = $qb->useResultCache(true, 600, 'UserInfo')
    ->getResult();

// DeleteAll namespace "User"
$qb = $this->getEntityManager()->createQuery();
$cacheDriver = $qb->getResultCacheDriver();
$cacheDriver->setNamespace('User');
$cacheDriver->deleteAll();

Call the cache driver and set namespace for DQL query with setNamespace().
If you execute deleteAll with the above code, the cache group whose namespace is “User” will be deleted.

That’s easy, but I’ve summarized how to use resultCache and how to set namespace.
I think you should see the details from the URL introduced in the text.