禁用主义查询缓存

mar*_*rcv 2 caching doctrine symfony doctrine-orm

在Doctrine存储库类中,以下代码产生以下结果:

$rsm = new ResultSetMapping;
$rsm->addEntityResult($this->_entityName, 'g');
$rsm->addFieldResult('g', 'geonameid', 'id');

$nativeQuery = $this->_em->createNativeQuery(
    "SELECT g.geonameid FROM mydb.geoname g WHERE g.geonameid = 2998268",
    $rsm
);

$r = $nativeQuery->getResult();

Debug::dump($r);
Run Code Online (Sandbox Code Playgroud)

结果:

array(1) {
    [0]=>
    object(stdClass)#461 (20) {
        ["__CLASS__"]=>
        string(40) "My\Bundle\Entity\Geonames\Geoname"
        ["id"]=>
        int(2998268)
        ["name"]=>
        NULL
        ["asciiname"]=>
        NULL
        ["latitude"]=>
        NULL
        ["longitude"]=>
        NULL
        ["fclass"]=>
        NULL
        ["fcode"]=>
        NULL
        ["countryCode"]=>
        NULL
        ["cc2"]=>
        NULL
        ["admin1Code"]=>
        NULL
        ["admin2Code"]=>
        NULL
        ["admin3Code"]=>
        NULL
        ["admin4Code"]=>
        NULL
        ["population"]=>
        NULL
        ["elevation"]=>
        NULL
        ["gtopo30"]=>
        NULL
        ["timezone"]=>
        NULL
        ["moddate"]=>
        NULL
    }
}
Run Code Online (Sandbox Code Playgroud)

这个(几乎)空的对象是正确的结果。这是我期望得到的。但是,如果我在代码前加上$test = $this->find(2998268);,则$nativequery结果不再为空:

array(1) {
    [0]=>
    object(stdClass)#424 (20) {
        ["__CLASS__"]=>
        string(40) "My\Bundle\Entity\Geonames\Geoname"
        ["id"]=>
        int(2998268)
        ["name"]=>
        string(8) "Limousin"
        ["asciiname"]=>
        string(8) "Limousin"
        ["latitude"]=>
        string(10) "45.7666700"
        ["longitude"]=>
        string(9) "1.7000000"
        ["fclass"]=>
        string(1) "A"
        ["fcode"]=>
        string(4) "ADM1"
        ["countryCode"]=>
        string(2) "FR"
        ["cc2"]=>
        string(0) ""
        ["admin1Code"]=>
        string(2) "B1"
        ["admin2Code"]=>
        string(0) ""
        ["admin3Code"]=>
        string(0) ""
        ["admin4Code"]=>
        string(0) ""
        ["population"]=>
        int(737001)
        ["elevation"]=>
        int(0)
        ["gtopo30"]=>
        int(534)
        ["timezone"]=>
        string(12) "Europe/Paris"
        ["moddate"]=>
        string(8) "DateTime"
    }
}
Run Code Online (Sandbox Code Playgroud)

我非常怀疑我$nativequery现在是从某个缓存(未设置)中获取对象的,但是我不想这么做。我仍然希望得到与以前从未打电话find()过的结果相同的结果。

我能怎么做?

我尝试了以下方法:

$r = $nativeQuery
        ->setCacheMode(Cache::MODE_GET)
        ->setCacheable(true)
        ->getResult();
Run Code Online (Sandbox Code Playgroud)

但是我收到一条错误消息说Call to undefined method Doctrine\ORM\NativeQuery::setCacheMode()

我也尝试设置$nativeQuery->useResultCache(false)但没有效果。

我正在使用以下版本的Doctrine组件:

doctrine/annotations           v1.2.6
doctrine/cache                 v1.4.1
doctrine/collections           v1.3.0
doctrine/common                v2.5.0
doctrine/dbal                  v2.5.1
doctrine/doctrine-bundle       v1.5.0
doctrine/doctrine-cache-bundle v1.0.1
doctrine/inflector             v1.0.1
doctrine/instantiator          1.0.5
doctrine/lexer                 v1.0.1
doctrine/orm                   v2.4.7
Run Code Online (Sandbox Code Playgroud)

小智 7

我的猜测是,当您调用时$this->find(2998268);,Doctrine会加载整个实体。然后,当您调用NativeQuery时,EntityManager会发现该实体已经在管理具有相同ID的完全相同的实体,并返回已经水化的实体。如果EntityManager->clear()find()和NativeQuery 之间进行调用,则应获得预期的结果。