Second level cache does not support scalar results. #5644

Closed
opened 2026-01-22 15:13:36 +01:00 by admin · 5 comments
Owner

Originally created by @lcp0578 on GitHub (Aug 16, 2017).

Originally assigned to: @lcobucci on GitHub.

#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

Originally created by @lcp0578 on GitHub (Aug 16, 2017). Originally assigned to: @lcobucci on GitHub. ```yml #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 ``` ```php /** * 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
admin added the InvalidQuestion labels 2026-01-22 15:13:36 +01:00
admin closed this issue 2026-01-22 15:13:36 +01:00
Author
Owner

@lcobucci commented on GitHub (Aug 16, 2017):

@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 commented on GitHub (Aug 16, 2017): @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.
Author
Owner

@lcp0578 commented on GitHub (Aug 17, 2017):

@lcobucci thanks, i got it.

@lcp0578 commented on GitHub (Aug 17, 2017): @lcobucci thanks, i got it.
Author
Owner

@simPod commented on GitHub (Aug 5, 2018):

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

@simPod commented on GitHub (Aug 5, 2018): @lcp0578 would you please share how do you use result set cache? I don't want to use partial objects either.
Author
Owner

@lcp0578 commented on GitHub (Aug 6, 2018):

@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 commented on GitHub (Aug 6, 2018): @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
Author
Owner

@simPod commented on GitHub (Aug 6, 2018):

@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.

@simPod commented on GitHub (Aug 6, 2018): @lcp0578 Thx, pointed me the right direction ```php $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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5644