Orm 条令结果缓存破坏实体删除

Orm 条令结果缓存破坏实体删除,orm,doctrine,Orm,Doctrine,我在使用ORM的结果缓存时遇到问题。该应用程序通过JSON REST接口管理创建/删除频道实体和向频道添加数据以进行监控。出于性能原因,跨请求缓存通道实体是可取的,因为它们大多是静态的 在单元测试过程中,我们发现流存在问题1)创建通道2)添加数据和3)删除通道。下面的代码中使用了一个新的实体管理器来模拟单独的JSON请求以进行测试: public function run() { // 1) add channel $this->em = self::createEntit

我在使用ORM的结果缓存时遇到问题。该应用程序通过JSON REST接口管理创建/删除频道实体和向频道添加数据以进行监控。出于性能原因,跨请求缓存通道实体是可取的,因为它们大多是静态的

在单元测试过程中,我们发现流存在问题1)创建通道2)添加数据和3)删除通道。下面的代码中使用了一个新的实体管理器来模拟单独的JSON请求以进行测试:

public function run() {
    // 1) add channel
    $this->em = self::createEntityManager();
    $channel = new Model\Channel('power');
    echo($uuid = $channel->getUuid());

    $this->setProperties($channel, array('title'=>'Meter', 'resolution'=>100));

    $this->em->persist($channel);
    $this->em->flush();
    $this->clearCache();

    // 2) add data
    $this->em = self::createEntityManager();
    $channel = $this->get($uuid);
    $this->dumpEntityState($channel, 'add ');

    $channel->addData(new Model\Data($channel, 1000000, 1));
    $this->em->flush();
    $this->dumpEntityState($channel, 'adddata ');

    // this fixes the problem
    // $this->clearCache();

    // 3) delete channel
    $this->em = self::createEntityManager();
    $entity = $this->get($uuid);
    $this->dumpEntityState($channel, 'delete ');

    if ($entity instanceof Model\Channel) {
        $entity->clearData($this->em);
    }

    $this->em->remove($entity);
    $this->em->flush();
    $this->clearCache();
}
通道实体由其标识符检索:

public function get($uuid) {
    if (!Util\UUID::validate($uuid)) {
        throw new \Exception('Invalid UUID: \'' . $uuid . '\'');
    }

    $dql = 'SELECT a, p
        FROM Volkszaehler\Model\Entity a
        LEFT JOIN a.properties p
        WHERE a.uuid = :uuid';

    $q = $this->em->createQuery($dql);
    $q->setParameter('uuid', $uuid);

    // this breaks the app
    $q->useResultCache(true);

    try {
        return $q->getSingleResult();
    } catch (\Doctrine\ORM\NoResultException $e) {
        throw new \Exception('No entity found with UUID: \'' . $uuid . '\'', 404);
    }
}
现在的问题是,一旦使用了
useResultCache(true)
,在步骤3)中删除实体将导致错误:

Uncaught exception 'InvalidArgumentException' with message 'A detached entity can not be removed.' in \ORM\UnitOfWork.php
只要
useResultCache()
false
,问题就消失了

resultCache如何影响实体的删除,尤其是当通道实体更新时结果缓存被清除时

更新

检查通道实体状态在向现有实体管理器中新检索的实体添加数据后,其状态已分离。这也是结果缓存第一次发挥作用


结果缓存是如何/为什么使实体分离的?

答案可以从原则中找到:缓存的实体总是“分离的”。如果您需要一个托管实体,您可以将其合并,但需要额外的DB查询

结论

如果删除等操作需要托管实体,最好不要使用缓存的查询结果

更新

这种行为在原则2.3中已经改变-缓存的结果现在总是含水的,因此被管理