How do I force doctrine to reload the data from the database?

霸气de小男生 提交于 2019-12-20 11:48:08

问题


I'm using doctrine/mongodb 1.0.0-BETA1 in a symfony2.1 install.

So i'm trying to force my repository to call data from my database instead of using the object it has cached.

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

.... do something somewhere to change the object ....

At this point if I call

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

The audit data hasn't changed. It still has the object it originally fetched. If I try to

$dm->refresh($audit) 

I get the same thing. Is there anyway for me to go back to the database for the value?


回答1:


Have you flushed your changes to the $audit object?

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

Every time you do a findBy(...) or findOneBy(...) it actually fetches a new document from the DB. (you should see the query in the Symfony profiler)

With a find() instead, it will fetch the document from his internal proxy cache. The Documents stay in the proxy cache until you call the $dm->clear() method.




回答2:


This worked for me:

$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);



回答3:


Adding to the previous answers, I was searching how to refresh the database of an Entity, not of a Document but the solution was close. I'm posting it here for others stumbling on this page with the same problem.

In one of my functional tests, I was using two times the same query:

$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

Then the tests goes through a process of changing the password. I then re-queried the user to compare if the password hash had changed with the same query:

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

The problem was that even though the tested controller updated the hash, the entity manager had the entity in cache.

So, the solution was to add the following between the two queries:

$em->clear();

And now, the password hash changed between queries ! Yay !




回答4:


When you deal with related entities, if you modify the related entities and save them through the parent object, you will have to add an option cascade={"detach"} for the detach to be effective.

For example, let's say you want to update a list of Friends on a Person object, by adding new objects to the list, removing some of them and updating some existing ones. You're going to have

$em->flush();
$em->detach($entity);

And in your Person entity make sure to update your friends relation :

@ORM\OneToMany(targetEntity="Somewhere\PeopleBundle\Entity\Person", mappedBy="person", cascade={"detach"})
private $friends;



回答5:


You can use method refresh :

$post; # modified
$entityManager->refresh();
$post; # reset from db



回答6:


Try something like

$dm->getUnitOfWork()->clear('WGenSimschoolsBundle:Audit');


来源:https://stackoverflow.com/questions/14761833/how-do-i-force-doctrine-to-reload-the-data-from-the-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!