通过QueryBuilder更新后已经水化的实体同步

时间:2017-02-09 12:25:09

标签: php doctrine-orm

在使用查询构建器更新后,我有一个简单的问题,它附加到已加载的实体,它们似乎是" desynchronize"。

以下代码显示了问题

/** @var  EntityManager $em */
$repository = new PersonneRepository();
/** @var Personne $persone */
$persone = $repository->find('42');

echo 'SEXE : ' . $persone->getSexe() . "\n";

$invertedSexe = $persone->getSexe() == 'F' ? 'M' : 'F';
echo 'New Sexe : '.$invertedSexe."\n";
$q = $em->createQueryBuilder();
$q->update($repository->getClassName(), 'p')
 ->set('p.sexe', ":sexe")
 ->where('p.id = :id')
 ->setParameters(array(
     'sexe' => $invertedSexe,
     'id' => $persone->getId()
 ));
$q->getQuery()->execute();
echo 'SEXE : ' . $persone->getSexe() . "\n";
$persone = $repository->find('42');
echo 'SEXE : ' . $persone->getSexe() . "\n";

输出:

SEXE : M
New Sexe : F
SEXE : M
SEXE : M

2 个答案:

答案 0 :(得分:1)

因为您在更新数据库时没有更新$ persone对象。

所以要么你去

  1. ORM方式意味着你$persone->setSexe()然后将其冲洗
  2. 这看起来像是......:

    /** @var  EntityManager $em */
    $repository = new PersonneRepository();
    /** @var Personne $persone */
    $persone = $repository->find('42');
    
    echo 'SEXE : ' . $persone->getSexe() . "\n";
    
    $invertedSexe = $persone->getSexe() == 'F' ? 'M' : 'F';
    echo 'New Sexe : '.$invertedSexe."\n";
    
    $persone->setSexe($invertedSexe);
    $em->persist($persone);
    $em->flush();
    
    echo 'SEXE : ' . $persone->getSexe() . "\n";
    $persone = $repository->find('42');
    echo 'SEXE : ' . $persone->getSexe() . "\n";
    
    1. DBAL方式,这意味着您先更新数据库,然后再次刷新$ person(find它仍然可以获得对象而不是更新的数据库实体)或设置$ persone->手动性。
    2. 选项2中提到的刷新在您的代码中完成:

       $em->refresh($persone); // instead of your last $respository->find('42');
      

答案 1 :(得分:0)

答案在文档中:

  

DQL UPDATE语句直接移植到Database UPDATE中   声明因此绕过任何锁定方案,事件而不是   增加版本列。已加载的实体   持久化上下文不会与更新的数据库同步   州。建议调用EntityManager#clear()并检索   任何受影响实体的新实例。

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#update-queries