如何强制学说从数据库重新加载数据?

daS*_*wie 36 doctrine-odm symfony-2.1

我在symfony2.1安装中使用doctrine/mongodb 1.0.0-BETA1.

所以我试图强制我的存储库从我的数据库调用数据,而不是使用它已缓存的对象.

$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");

.... do something somewhere to change the object ....
Run Code Online (Sandbox Code Playgroud)

此时如果我打电话

$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");
Run Code Online (Sandbox Code Playgroud)

审计数据没有改变.它仍然具有它最初获取的对象.如果我试着

$dm->refresh($audit) 
Run Code Online (Sandbox Code Playgroud)

我得到了同样的东西.反正我有没有回到数据库中获取价值?

Mad*_*rco 54

你是否刷新了$audit对象的更改?

$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");
//do something somewhere to change the object
$dm->flush();
Run Code Online (Sandbox Code Playgroud)

每次执行findBy(...)findOneBy(...)实际从DB中获取新文档时.(您应该在Symfony探查器中看到查询)

使用find()代替它,它将从内部代理缓存中获取文档.在您调用$dm->clear()方法之前,文档将保留在代理缓存中.

  • 在我的情况下(参见我的回答),`findOneBy`也确实使用了缓存!我不得不使用`$ em-> clear();` (17认同)
  • +1代表代理缓存说明 (3认同)
  • 清除删除缓存中保存的所有实体,因此,如果用户被持久化(例如),学说将抛出错误,因为它不知道这个现有用户,并且学说建议应用“级联持久化”来添加它。但该用户已经存在。所以这个解决方案在这种情况下并不有效。据我所知,最好的解决方案是使用“$entityManager->refresh($entity);”来强制直接从数据库重新加载实体。 (3认同)

fde*_*tri 26

这对我有用:

$doc = $this->documentManager->getRepository('MyBundle:MyDoc')->find($id);

/* ... in the meanwhile another external process is doing some changes to the object ...*/
$doc = $this->documentManager->getRepository('MyBundle:MyDoc')->find($id); // Perhaps this is not useful
$this->documentManager->refresh($doc);
Run Code Online (Sandbox Code Playgroud)

  • 感谢您指向刷新选项-多年来一直在寻找它 (2认同)

ach*_*zot 23

添加到以前的答案,我正在搜索如何刷新数据库Entity,而不是一个Document但解决方案是关闭的.我在这里发布它,因为其他人在这个页面上遇到了同样的问题.

在我的一个功能测试中,我使用了两次相同的查询:

$em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
$user = $em->getRepository('AcmeUserBundle:User')->findOneBy(array('email' => 'james.bond@secure.gov.co.uk'));
echo "Old hash: ".$user->getPassword() . "\n";
// result: 8bb6118f8fd6935ad0876a3be34a717d32708ffd
Run Code Online (Sandbox Code Playgroud)

然后测试通过更改密码的过程.然后,我重新询问用户,以比较密码哈希是否已使用相同的查询更改:

$user = $em->getRepository('AcmeUserBundle:User')->findOneBy(array('email' => 'james.bond@secure.gov.co.uk'));
echo "New hash: ".$user->getPassword() . "\n";
// result: 8bb6118f8fd6935ad0876a3be34a717d32708ffd # Same !
Run Code Online (Sandbox Code Playgroud)

问题是即使测试的控制器更新了散列,实体管理器也将实体放在缓存中.

因此,解决方案是在两个查询之间添加以下内容:

$em->clear();
Run Code Online (Sandbox Code Playgroud)

而现在,密码哈希在查询之间发生了变化!好极了 !


小智 7

您可以使用方法刷新:

$post; # modified
$entityManager->refresh();
$post; # reset from db
Run Code Online (Sandbox Code Playgroud)