Подтвердить что ты не робот

Как заставить доктрину перезагружать данные из базы данных?

Я использую doctrine/mongodb 1.0.0-BETA1 в установке symfony2.1.

Итак, я пытаюсь заставить мой репозиторий вызывать данные из моей базы данных, а не использовать объект, который он кэшировал.

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

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

В этот момент, если я вызываю

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

Данные аудита не изменились. У него все еще есть объект, который он изначально приносил. Если я попытаюсь

$dm->refresh($audit) 

Я получаю то же самое. Есть ли в любом случае для меня вернуться к базе данных для значения?

4b9b3361

Ответ 1

Вы сбросили изменения в объект $audit?

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

Каждый раз, когда вы выполняете findBy(...) или findOneBy(...), он на самом деле извлекает новый документ из БД. (вы должны увидеть запрос в профилировщике Symfony)

С помощью find() он извлечет документ из своего внутреннего прокси-кеша. Документы остаются в прокси-кеше до тех пор, пока вы не вызовете метод $dm->clear().

Ответ 2

Это сработало для меня:

$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

Добавляя к предыдущим ответам, я искал, как обновить базу данных Entity, а не Document, но решение было близко. Я размещаю его здесь, чтобы другие наткнулись на эту страницу с той же проблемой.

В одном из моих функциональных тестов я использовал два раза тот же запрос:

$em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
$user = $em->getRepository('AcmeUserBundle:User')->findOneBy(array('email' => '[email protected]'));
echo "Old hash: ".$user->getPassword() . "\n";
// result: 8bb6118f8fd6935ad0876a3be34a717d32708ffd

Затем тесты проходят через процесс смены пароля. Затем я повторно попросил пользователя сравнить, изменился ли хэш пароля с тем же запросом:

$user = $em->getRepository('AcmeUserBundle:User')->findOneBy(array('email' => '[email protected]'));
echo "New hash: ".$user->getPassword() . "\n";
// result: 8bb6118f8fd6935ad0876a3be34a717d32708ffd # Same !

Проблема заключалась в том, что, несмотря на то, что тестируемый контроллер обновил хэш, диспетчер сущности имел объект в кеше.

Итак, решение заключалось в том, чтобы добавить между двумя запросами следующее:

$em->clear();

И теперь хеш пароля изменился между запросами! Yay!

Ответ 4

Когда вы имеете дело с связанными объектами, если вы изменяете связанные объекты и сохраняете их через родительский объект, вам нужно будет добавить параметр cascade = { "detach" } для эффективного удаления.

Например, скажем, вы хотите обновить список друзей в объекте Person, добавив в список новые объекты, удалив некоторые из них и обновив некоторые из существующих. У вас будет

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

И в вашем объекте Person обязательно обновите отношение ваших друзей:

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

Ответ 5

Вы можете использовать обновление метода:

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

Ответ 6

Попробуйте что-нибудь вроде

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