2012-09-05 15 views
6

Ho un documento con un documento incorporato. Quando creo un oggetto per la prima volta tutto funziona correttamente, ma quando provo ad aggiornare un documento, il documento incorporato non viene aggiornato.Come aggiornare i documenti incorporati in Doctrine MongoDB?

Nella mia domanda interrogare un documento, aggiornare i valori e persisterli nell'archivio dati.

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

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

Se non aggiorno il documento incorporato, ma impostare una nuova tutto funziona bene:

// 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(); 

Come ho detto, Variante B funziona bene. Tuttavia, nella mia applicazione i documenti sono più complessi e per me sarebbe poco pratico creare un nuovo oggetto per il documento incorporato ogni volta che devo aggiornarlo. Esiste un metodo per dire a Doctrine ODM di esaminare i valori di un documento incorporato per decidere se deve essere aggiornato?

risposta

0

MongoDB ha solo operazioni atomiche. Hai opzioni: 1. Interrogare il documento, trovare il documento secondario appropriato, aggiornare l'intero documento o la sua parte. Pro: logica facile Contro: non atomico 2. Utilizzare l'operatore posizionale $ se i propri documenti secondari sono in elenco.

2

Ho affrontato esattamente lo stesso problema. Si scopre che UnitOfWork sembra fallire nel calcolo dei changeset di documenti con altri documenti incorporati, anche se non sono stato in grado di capire perché ... Come risultato, quando confronto il valore effettivo e quello originale, unità di lavoro mostra lo stesso valore per entrambi. Parlando con la vostra variante A, quando si

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

Unità di lavoro mostra "foo baz" sia per il vecchio e il nuovo valore e non lo riconoscerà come un cambiamento e vi Perciò non aggiornarlo.

In ogni caso, questo Leeds a una soluzione alternativa:

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

Questo rende l'unità di lavoro riconosce il DOCB di $ documento come un documento appena impostato e saranno svuotati come previsto.

+0

Problemi di sostituzione di un documento incorporato con uno diverso. Nel mio caso, DocumentB non è un EmbeddedDocument, ma piuttosto un documento. L'uso del distacco sull'oggetto come hai mostrato qui ha funzionato anche in questo scenario. – Onema

Problemi correlati