web-dev-qa-db-fra.com

Comment forcer doctrine pour recharger les données de la base de données?

J'utilise doctrine/mongodb 1.0.0-BETA1 dans une installation symfony2.1.

J'essaie donc de forcer mon référentiel à appeler des données de ma base de données au lieu d'utiliser l'objet qu'il a mis en cache.

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

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

À ce stade, si j'appelle

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

Les données d'audit n'ont pas changé. Il a toujours l'objet récupéré à l'origine. Si j'essaye de

$dm->refresh($audit) 

Je reçois la même chose. Est-il possible pour moi de revenir à la base de données pour la valeur?

34
daSn0wie

Avez-vous vidé vos modifications apportées à l'objet $audit?

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

Chaque fois que vous effectuez une findBy(...) ou findOneBy(...), elle récupère en fait un nouveau document de la base de données. (vous devriez voir la requête dans le profileur Symfony)

Avec un find () à la place, il récupérera le document de son cache proxy interne. Les documents restent dans le cache proxy jusqu'à ce que vous appeliez la méthode $dm->clear().

50
Madarco

Cela a fonctionné pour moi:

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

En plus des réponses précédentes, je cherchais comment rafraîchir la base de données d'un Entity, pas d'un Document mais la solution était proche. Je le poste ici pour que d'autres trébuchent sur cette page avec le même problème.

Dans l'un de mes tests fonctionnels, j'utilisais deux fois la même requête:

$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

Ensuite, les tests passent par un processus de modification du mot de passe. J'ai ensuite demandé à l'utilisateur de comparer si le hachage du mot de passe avait changé avec la même requête :

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

Le problème était que même si le contrôleur testé mettait à jour le hachage, le gestionnaire d'entité avait l'entité dans cache.

Ainsi, la solution consistait à ajouter ce qui suit entre les deux requêtes:

$em->clear();

Et maintenant, le hachage du mot de passe a changé entre les requêtes! Yay !

22
achedeuzot

Vous pouvez utiliser l'actualisation de la méthode:

$post; # modified
$entityManager->refresh();
$post; # reset from db
2
حمید

Lorsque vous traitez avec des entités liées, si vous modifiez les entités liées et les enregistrez via l'objet parent, vous devrez ajouter une option cascade = {"detach"} pour que le détachement soit efficace.

Par exemple, supposons que vous souhaitiez mettre à jour une liste d'amis sur un objet Personne, en ajoutant de nouveaux objets à la liste, en supprimant certains et en mettant à jour certains existants. Tu vas avoir

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

Et dans votre entité Personne, assurez-vous de mettre à jour votre relation d'amis:

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

Essayez quelque chose comme

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