Orm: Second level cache does not support scalar results.

Created on 16 Aug 2017  路  5Comments  路  Source: doctrine/orm

#config.yml

# Doctrine Configuration
doctrine:
  ......
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        # enable metadata caching 
        metadata_cache_driver: redis 
        # enable query caching 
        query_cache_driver: redis 
        filters:
            kit_office_filter: KitBaseBundle\Doctrine\Filter\OfficeFilter
        # enable caching
        second_level_cache:
            region_cache_driver:
                type: service
                id: snc_second_level_cache
            enabled: true
            regions:
                entity_that_rarely_changes:
                    lifetime: 86400
                    cache_driver:
                        type: service
                        id: snc_second_level_cache
/**
 * District
 *
 * @ORM\Table(name="district",options={"comment": ""})
 * @ORM\Entity(repositoryClass="KitCaseBundle\Repository\DistrictRepository")
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE", region= "entity_that_rarely_changes")
 */
class District{}

// Repository
public function getChildren($pid, $toArray = false)
    {
        $qb = $this->createQueryBuilder('d');
        $qb->select('d.id,d.name,d.code,d.parentId')
            ->where('d.parentId = :pid AND d.status = :status')
            ->setParameters([
            'pid' => $pid,
            'status' => 1
        ]);
        if ($toArray) {
            return $qb->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
        } else {
            return $qb->getQuery()->setCacheable(true)->setCacheRegion('entity_that_rarely_changes')->getResult();
        }
    }

What's wrong ?

thanks

Invalid Question

All 5 comments

@lcp0578 L2C is for entities and associations, not scalar results. If you want that you should use result set cache.

The problem you're having is that d.id, d.name, d.code, d.parentId will not give an object but rather the data, if you want objects you should take a look at partial objects (but your cached data will probably not be complete).

I'd suggest you to just load the object instead or relying on result set cache instead of L2C.

@lcobucci thanks, i got it.

@lcp0578 would you please share how do you use result set cache? I don't want to use partial objects either.

@simPod I don't use second level cache,it it for associations.There is my note, hope help you.
https://github.com/lcp0578/cheat-sheets/blob/master/src/symfony/Doctrine/DoctrineCache.md

@lcp0578 Thx, pointed me the right direction

        $cache = $this->entityManager->getConfiguration()->getResultCacheImpl();

        return $this->entityManager->createQueryBuilder()
            ->addSelect(...)
            ...
            ->getQuery()
            ->setResultCacheProfile(new QueryCacheProfile())
            ->setHydrationCacheProfile(new QueryCacheProfile(0, null, $cache))
            ->useQueryCache(true)
            ->useResultCache(true)
            ->getArrayResult();

A bit weird tho, eg. getting cache implementation from configuration and then injecting it back via setHydrationCacheProfile somehow doesn't feel right.

Was this page helpful?
0 / 5 - 0 ratings