2012-09-05 20 views
6

Tengo un documento que tiene un documento incrustado. Cuando creo un objeto por primera vez todo funciona bien, pero cuando intento actualizar un documento, el documento incrustado no se actualiza.¿Cómo actualizo documentos incrustados en Doctrine MongoDB?

/** @MongoDB\Document */ 
class DocumentA 
{ 
    /** @MongoDB\EmbedOne(targetDocument="DocumentB") **/ 
    protected $docB; 

    /** @MongoDB\String */ 
    protected $valueA; 
} 

/** @MongoDB\EmbeddedDocument */ 
class DocumentB 
{ 
    /** @MongoDB\String */ 
    protected $valueB; 
} 

En mi aplicación consulto un documento, actualizo los valores y los conservo en el almacén de datos.

// Variant A – Does not work 
$document = ... // find from data store 
$document->setValueA('Hello World'); 
$document->getDocB()->setValueB('foo baz'); 

$om->persist($document); 
$om->flush(); 

Si no actualizo el documento incrustado, pero especificar una nueva todo funciona bien:

// Variant B - Does work 
$document = ... // find from data store 
$document->setValueB('Hello World 2'); 
$document->setDocB(new DocumentB()); 
$document->getDocB()->setValueB('foo baz 2'); 

$om->persist($document); 
$om->flush(); 

Como ya he dicho, la variante B funciona bien. Sin embargo, en mi aplicación los documentos son más complejos y no sería práctico para mí crear un nuevo objeto para el documento incrustado cada vez que tengo que actualizarlo. ¿Hay algún método para decirle a Doctrine ODM que mire los valores de un documento incrustado para decidir si debe actualizarse?

Respuesta

0

MongoDB solo tiene operaciones atómicas. Tiene opciones: 1. Consulte el documento, busque el subdocumento apropiado, actualice el documento completo o su parte. Pros: lógica fácil Contras: no atómico 2. Usar el operador posicional $ es sus subdocumentos están en la lista.

2

Me enfrenté exactamente al mismo problema. Resulta que UnitOfWork parece fallar en el cálculo de los conjuntos de cambios de documentos con otros documentos incrustados, aunque no he podido averiguar por qué ... Como resultado, cuando comparo el valor real y el original, unidad de trabajo muestra el mismo valor para ambos. Hablando con su variante A, cuando

$document->getDocB()->setValueB('foo baz'); 

Unidad de trabajo muestra "Baz foo", tanto para el viejo y el nuevo valor y no lo reconocerá como un cambio y va para ello no actualizarlo.

De todos modos, esta Leeds a una solución:

$document = ... // find from data store 
$document->setValueA('Hello World'); 
$docB = $document->getDocB(); 
$docB->setValueB('foo baz'); 
$om->detach($docB); 
$om->persist($document); 
$om->flush(); 

Esto hace que la unidad de trabajo reconoce la docB de $ documento como un documento de nueva creación y tirar de la cadena como se esperaba.

+0

Estaba teniendo problemas para reemplazar un documento incrustado por uno diferente. En mi caso, DocumentB no es un documento incrustado sino más bien un documento. El uso de separar el objeto como el que se muestra aquí también funcionó en este escenario. – Onema

Cuestiones relacionadas