symfony 2.1 - ¿Cómo fuerzo la doctrina para recargar los datos de la base de datos?
symfony-2.1 doctrine-odm (6)
Estoy usando doctrine / mongodb 1.0.0-BETA1 en una instalación symfony2.1.
Así que estoy tratando de forzar a mi repositorio a llamar datos de mi base de datos en lugar de usar el objeto que ha almacenado en caché.
$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");
.... do something somewhere to change the object ....
En este punto si llamo
$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");
Los datos de auditoría no han cambiado. Todavía tiene el objeto que originalmente fue recuperado. Si intento
$dm->refresh($audit)
Me sale lo mismo. ¿Hay alguna forma de que regrese a la base de datos para obtener el valor?
¿Ha vaciado sus cambios al objeto $audit
?
$audit = $dm->getRepository("WGenSimschoolsBundle:Audit")->findOneById("xxxx");
//do something somewhere to change the object
$dm->flush();
Cada vez que haces un findBy(...)
o findOneBy(...)
en realidad se obtiene un nuevo documento de la base de datos. (deberías ver la consulta en el perfilador de Symfony)
Con un find () en su lugar, recuperará el documento de su caché de proxy interno. Los Documentos permanecen en el caché de proxy hasta que llame al $dm->clear()
.
Agregando a las respuestas anteriores, estaba buscando cómo actualizar la base de datos de una Entity
, no de un Document
pero la solución estaba cerca. Lo estoy publicando aquí para que otros tropiecen en esta página con el mismo problema.
En una de mis pruebas funcionales, estaba usando dos veces la misma consulta:
$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
Luego las pruebas pasan por un proceso de cambio de contraseña. Luego volví a consultar al usuario para comparar si el hash de la contraseña había cambiado con la misma consulta:
$user = $em->getRepository(''AcmeUserBundle:User'')->findOneBy(array(''email'' => ''[email protected]''));
echo "New hash: ".$user->getPassword() . "/n";
// result: 8bb6118f8fd6935ad0876a3be34a717d32708ffd # Same !
El problema fue que aunque el controlador probado actualizó el hash, el administrador de entidades tenía la entidad en caché .
Entonces, la solución fue agregar lo siguiente entre las dos consultas:
$em->clear();
Y ahora, ¡el hash de contraseña cambió entre consultas! Hurra !
Cuando trate con entidades relacionadas, si modifica las entidades relacionadas y las guarda a través del objeto principal, tendrá que agregar una opción en cascada = {"separar"} para que la separación sea efectiva.
Por ejemplo, supongamos que desea actualizar una lista de amigos en un objeto de Persona, agregando nuevos objetos a la lista, eliminando algunos de ellos y actualizando algunos existentes. Vas a tener
$em->flush();
$em->detach($entity);
Y en la entidad de tu Persona, asegúrate de actualizar la relación de tus amigos:
@ORM/OneToMany(targetEntity="Somewhere/PeopleBundle/Entity/Person", mappedBy="person", cascade={"detach"})
private $friends;
Esto funcionó para mí:
$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);
Intenta algo como
$dm->getUnitOfWork()->clear(''WGenSimschoolsBundle:Audit'');
Puede utilizar la actualización del método:
$post; # modified
$entityManager->refresh();
$post; # reset from db