Child entity not retrieved from array cache #6379

Closed
opened 2026-01-22 15:32:02 +01:00 by admin · 6 comments
Owner

Originally created by @peterkeatingie on GitHub (Jan 3, 2020).

Bug Report

BC Break | no
Version | 2.7.0

Summary

Entity which is extended from a base class is not retrieved from array cache when using the second level cache.
ZF3 application.

Current behavior

Base class is abstract, with extending class as a child, using single table inheritance and second level cache.
When retrieving the child class using the findBy repository method, calls subsequent to the first one are not found in the cache. The entity is fetched from the database each time.

It looks to me like the entity is put into the cache with a key which is based on its child name but retrieval is attempted using the base class name.

How to reproduce

Entity definitions:

Base class:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name="Gts\Base\Entity\Base" table="base" inheritance-type="SINGLE_TABLE">
        <id name="id" type="integer" column="id">
            <generator strategy="IDENTITY"/>
        </id>
        <field name="someField"/>
    </entity>
</doctrine-mapping>

Child class. Here the cache usage is set:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
    <entity name="Gts\Base\Entity\BaseChild" extends="base">
        <cache usage="NONSTRICT_READ_WRITE" />
        <field name="someNewField"/>
    </entity>
</doctrine-mapping>

Doctrine configuration:

'second_level_cache' => [
                    'enabled' => true,
                ],

Calling fetch several times leads to a new db call each time (this is BaseChild repo):

// Doctrine\ORM\EntityRepository
        $this->repository->findBy([
            'someField' => 'Some Field Value',
        ]);

        $this->repository->findBy([
            'someField' => 'Some Field Value',
        ]);

Query log:

INFO: Total time: [0.0005791187286377], from: `base` Executed Query: {"sql":"SELECT t0.someField AS someField_1, t0.id AS id_2, t0.someNewField AS someNewField_3, t0.dtype FROM base t0 WHERE t0.someField = ? AND t0.dtype IN ('basechild')","params":["Some Field Value"],"types":["string"],"executionMS":0.0005791187286376953} [] []
INFO: Total time: [0.00084710121154785], from: `base` Executed Query: {"sql":"SELECT t0.someField AS someField_1, t0.id AS id_2, t0.someNewField AS someNewField_3, t0.dtype FROM base t0 WHERE t0.someField = ? AND t0.dtype IN ('basechild')","params":["Some Field Value"],"types":["string"],"executionMS":0.00026798248291015625} [] []

During debugging, I see that the entity is put into the array cache after the first call to the repository with the following key:

DoctrineModule:gts_base_entity_basechild[gts_base_entity_basechild_gts.base.entity.basechild_1][1]

But when retrieving the following key is used to find the entry:

DoctrineModule:gts_base_entity_basechild[gts_base_entity_basechild_gts.base.entity.base_1][1]

The reason for this is that in Doctrine\ORM\Cache\DefaultQueryCache::put (line 284) the cache key comes from the found entity however the key to retrieve comes from the root entity name in Doctrine\ORM\Cache\DefaultQueryCache::get (line 121).

Expected behavior

The second call to the repository should get the entity from the cache instead of making another query on the DB.

Of course it's possible that I'm missing some configuration and this may be expected as I have it configured - in which case any guidance regarding the configuration would be much appreciated.

This works as I would expect on any entity which does not have a base class.

Originally created by @peterkeatingie on GitHub (Jan 3, 2020). ### Bug Report BC Break | no Version | 2.7.0 #### Summary Entity which is extended from a base class is not retrieved from array cache when using the second level cache. ZF3 application. #### Current behavior Base class is abstract, with extending class as a child, using single table inheritance and second level cache. When retrieving the child class using the findBy repository method, calls subsequent to the first one are not found in the cache. The entity is fetched from the database each time. It looks to me like the entity is put into the cache with a key which is based on its child name but retrieval is attempted using the base class name. #### How to reproduce Entity definitions: Base class: ``` <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Gts\Base\Entity\Base" table="base" inheritance-type="SINGLE_TABLE"> <id name="id" type="integer" column="id"> <generator strategy="IDENTITY"/> </id> <field name="someField"/> </entity> </doctrine-mapping> ``` Child class. Here the cache usage is set: ``` <?xml version="1.0" encoding="utf-8"?> <doctrine-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="Gts\Base\Entity\BaseChild" extends="base"> <cache usage="NONSTRICT_READ_WRITE" /> <field name="someNewField"/> </entity> </doctrine-mapping> ``` Doctrine configuration: ``` 'second_level_cache' => [ 'enabled' => true, ], ``` Calling fetch several times leads to a new db call each time (this is BaseChild repo): ``` // Doctrine\ORM\EntityRepository $this->repository->findBy([ 'someField' => 'Some Field Value', ]); $this->repository->findBy([ 'someField' => 'Some Field Value', ]); ``` Query log: ``` INFO: Total time: [0.0005791187286377], from: `base` Executed Query: {"sql":"SELECT t0.someField AS someField_1, t0.id AS id_2, t0.someNewField AS someNewField_3, t0.dtype FROM base t0 WHERE t0.someField = ? AND t0.dtype IN ('basechild')","params":["Some Field Value"],"types":["string"],"executionMS":0.0005791187286376953} [] [] INFO: Total time: [0.00084710121154785], from: `base` Executed Query: {"sql":"SELECT t0.someField AS someField_1, t0.id AS id_2, t0.someNewField AS someNewField_3, t0.dtype FROM base t0 WHERE t0.someField = ? AND t0.dtype IN ('basechild')","params":["Some Field Value"],"types":["string"],"executionMS":0.00026798248291015625} [] [] ``` During debugging, I see that the entity is put into the array cache after the first call to the repository with the following key: `DoctrineModule:gts_base_entity_basechild[gts_base_entity_basechild_gts.base.entity.basechild_1][1]` But when retrieving the following key is used to find the entry: `DoctrineModule:gts_base_entity_basechild[gts_base_entity_basechild_gts.base.entity.base_1][1]` The reason for this is that in Doctrine\ORM\Cache\DefaultQueryCache::put (line 284) the cache key comes from the found entity however the key to retrieve comes from the root entity name in Doctrine\ORM\Cache\DefaultQueryCache::get (line 121). #### Expected behavior The second call to the repository should get the entity from the cache instead of making another query on the DB. Of course it's possible that I'm missing some configuration and this may be expected as I have it configured - in which case any guidance regarding the configuration would be much appreciated. This works as I would expect on any entity which does not have a base class.
admin added the Bug label 2026-01-22 15:32:02 +01:00
admin closed this issue 2026-01-22 15:32:03 +01:00
Author
Owner

@peterkeatingie commented on GitHub (Jan 28, 2020):

Hi all, just checking to see if you had a chance to look at this since? Do you think it might be a bug?
Thanks,
Peter.

@peterkeatingie commented on GitHub (Jan 28, 2020): Hi all, just checking to see if you had a chance to look at this since? Do you think it might be a bug? Thanks, Peter.
Author
Owner

@SenseException commented on GitHub (Jan 28, 2020):

It was already labelled as a bug. Do you feel like you want to try to fix it in a pull request?

@SenseException commented on GitHub (Jan 28, 2020): It was already labelled as a bug. Do you feel like you want to try to fix it in a pull request?
Author
Owner

@peterkeatingie commented on GitHub (Jan 29, 2020):

Sure, let me see what I can do, thanks.

@peterkeatingie commented on GitHub (Jan 29, 2020): Sure, let me see what I can do, thanks.
Author
Owner

@peterkeatingie commented on GitHub (Feb 2, 2020):

PR: https://github.com/doctrine/orm/pull/8009

@peterkeatingie commented on GitHub (Feb 2, 2020): PR: https://github.com/doctrine/orm/pull/8009
Author
Owner

@peterkeatingie commented on GitHub (Feb 15, 2020):

New PR against 2.7 https://github.com/doctrine/orm/pull/8023

@peterkeatingie commented on GitHub (Feb 15, 2020): New PR against 2.7 https://github.com/doctrine/orm/pull/8023
Author
Owner

@beberlei commented on GitHub (Mar 1, 2020):

Fixed by #8023

@beberlei commented on GitHub (Mar 1, 2020): Fixed by #8023
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6379