doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.94k stars 2.52k forks source link

Call to a member function resolveAssociationEntries() on boolean {"detail":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function resolveAssociationEntries() on boolean at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Cache/DefaultQueryCache.php:140)"} #7266

Closed mingmingxianseng closed 5 years ago

mingmingxianseng commented 6 years ago

The following mistakes occur occasionally,and I can't find the solution

Call to a member function resolveAssociationEntries() on boolean {"detail":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function resolveAssociationEntries() on boolean at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Cache/DefaultQueryCache.php:140)"}

version: doctrine/orm V2.6.0 in DefaultQueryCache.php at line 140

        $entries   = $region->getMultiple($cacheKeys);
        // @TODO - move to cache hydration component
        foreach ($cacheEntry->result as $index => $entry) {
            $entityEntry = is_array($entries) && array_key_exists($index, $entries) ? $entries[$index] : null;

            if ($entityEntry === null) {
                if ($this->cacheLogger !== null) {
                    $this->cacheLogger->entityCacheMiss($regionName, $cacheKeys->identifiers[$index]);
                }

                return null;
            }

I think the parameter $entityEntry sometimes will be false , then occur the mistakes.

change if ($entityEntry === null) to if ($entityEntry === null || $entityEntry === false ) . Is this a good solution ?

I need your help. Thank you very much.

javabudd commented 6 years ago

+1

This issue started happening to me when I switched my redis maxmemory-policy to allkeys-lru

https://aws.amazon.com/premiumsupport/knowledge-center/oom-command-not-allowed-redis/

Ocramius commented 6 years ago

Also on newer releases?

On Wed, 15 Aug 2018, 06:41 javabudd, notifications@github.com wrote:

+1

This issue started happening to me when I switched my redis maxmemory-policy to allkeys-lru

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/doctrine/doctrine2/issues/7266#issuecomment-413092535, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJakJ8-mq2jbPd2iWhz8UMRSITWb-dNks5uQ6aSgaJpZM4Us3BS .

javabudd commented 6 years ago

I'm currently on 2.6.2

Ocramius commented 6 years ago

Fixing the conditional is incorrect there: would need to change the fetch operation so that multiple misses don't become false[]

Ocramius commented 6 years ago

Can this be reproduced with a failing test case?

javabudd commented 6 years ago

I'll try and reproduce

mingmingxianseng commented 6 years ago

   ## in  Doctrine\Common\Cache\RedisCache.php  +72

    protected function doFetchMultiple(array $keys)
    {
        $fetchedItems = array_combine($keys, $this->redis->mget($keys));

        // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
        $foundItems   = [];

        foreach ($fetchedItems as $key => $value) {
            # change this line to     if (false !== $value )
            if (false !== $value || $this->redis->exists($key)) {
                $foundItems[$key] = $value;
            }
        }

        return $foundItems;
    }

I create a new class extends RedisCache and change false !== $value || $this->redis->exists($key) to false !== $value.

The problem was solved temporarily.

Ocramius commented 6 years ago

Please don't suggest ugly workarounds when a solution here is possible:

  1. Send a test case
  2. Send a patch to the original code (including said test case)

On Thu, 16 Aug 2018, 05:35 mingmingxianseng, notifications@github.com wrote:

in Doctrine\Common\Cache\RedisCache.php +72

protected function doFetchMultiple(array $keys)
{
    $fetchedItems = array_combine($keys, $this->redis->mget($keys));

    // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
    $foundItems   = [];

    foreach ($fetchedItems as $key => $value) {
        # change this line to     if (false !== $value )
        if (false !== $value || $this->redis->exists($key)) {
            $foundItems[$key] = $value;
        }
    }

    return $foundItems;
}

I create a new class extends RedisCache and change false !== $value || $this->redis->exists($key) to false !== $value.

The problem was solved temporarily.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/doctrine/doctrine2/issues/7266#issuecomment-413414466, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJakAam814lzIA1o08lnhQf9ZjzzR30ks5uROhpgaJpZM4Us3BS .

mingmingxianseng commented 6 years ago

I don't think it's a code problem. maybe I didn't find it. maybe other code changed the cache. maybe my other code effected it. maybe redis's rules...eg.. It only happens in production environment in my project, so it is really hard to reproduce.

but the fact is that a cache is not a legitimate entity identifier, it is a false, shouldn't we judge whether this cache is legal ? i think make this cache miss is always better than throw a fatal error. so i took the interim plan as I mentioned in my last comment.

maybe it is a ugly workarounds, but it is really effective, isn't it .

And in our project, there will be no false in cache.

Forgive me for my poor English and my humble opinion. 😝

Ocramius commented 6 years ago

A cache miss can be emulated, and that's what should happen in the test scenario

On Fri, 17 Aug 2018, 09:22 mingmingxianseng, notifications@github.com wrote:

I don't think it's a code problem. maybe I didn't find it. maybe other code changed the cache. maybe my other code effected it. maybe redis's rules...eg.. It only happens in production environment in my project, so it is really hard to reproduce.

but the fact is that a cache is not a legitimate entity identifier, it is a false, shouldn't we judge whether this cache is legal ? i think make this cache miss is always better than throw a fatal error. so i took the interim plan as I mentioned in my last comment.

maybe it is a ugly workarounds, but it is really effective, isn't it .

And in our project, there will be no false in cache.

Forgive me for my poor English and my humble opinion. 😝

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/doctrine/doctrine2/issues/7266#issuecomment-413780620, or mute the thread https://github.com/notifications/unsubscribe-auth/AAJakBaqz_WAJUJrzY4BSlwzQCOKl5N3ks5uRm8fgaJpZM4Us3BS .

mingmingxianseng commented 6 years ago

normal cache's value's type is object . but in this case , the cache's value is "false". so it throw exception Call to a member function resolveAssociationEntries() on boolean .

Ocramius commented 6 years ago

Yes: let's put it in a test, reproduce the cache behavior there and figure out how to fix it afterwards (and only afterwards! Test comes first.) :-)

javabudd commented 5 years ago

Upgrading the Redis engine from 4 -> 5 seems to have alleviated the issue for me.

Ocramius commented 5 years ago

Closing here due to missing test scenario.

umpirsky commented 5 years ago

Same issue exists in v2.6.3.