2012-05-31 2 views
0

Мне не повезло с использованием merge(). Я делаю почти точно what is documented:doctrine ODM (mongodb) merge не работает

/* @var $detachedDocument MyDocumentClass */ 
$detachedDocument = unserialize($serializedDocument); 
$document = $dm->merge($detachedDocument); 
$document->setLastUpdated(new \MongoDate()); 
$dm->persist($document); 

но изменения не прилипает. Я должен сделать это вместо:

$dm->createQueryBuilder('MyDocumentClass') 
    ->findAndUpdate() 
    ->field('lastUpdated')->set(new \MongoDate()) 
    ->getQuery() 
    ->execute(); 

merge() кажется довольно простым, поэтому я запутался, почему это не работает, как я думаю, что это должно быть.

ответ

3

В первом примере кода, merge() с последующим persist() является излишним, и вы опустили в flush(), которая является единственной операцией, которая будет на самом деле запись в базу данных (если вы не выполнить запрос вручную, как вы делали это во втором примере). Если вы пройдете через код в UnitOfWork::doMerge(), вы увидите, что он будет либо продолжать объект (если он не имеет идентификатора), либо получить документ по его идентификатору. Конечным результатом является то, что merge() возвращает управляемый документ. Persist гарантирует, что документ будет управляться после его вызова (он сам ничего не возвращает). Если вы ткнете в UnitOfWork::doPersist(), вы увидите, что передача управляемого объекта методу является фактически NOOP.

Попробуйте заменить persist() на flush(). Обратите внимание, что при необходимости можно очистить один документ, но $dm->flush() по умолчанию обрабатывает все управляемые объекты.

Если это все еще не помогает, я бы подтвердил, что поле lastUpdated правильно отображается в ODM. Вы можете проверить вывод $dm->getClassMetadata('MyDocumentClass') для подтверждения. Если это не поле с отображением, UnitOfWork не обнаружит изменений в документе, и ничего не будет скрыто.

В качестве альтернативы: во втором примере кода вы выполняете findAndUpdate() без каких-либо критериев поиска (указывается только set()). Как правило, вы должны соединить модификацию с чем-то вроде equals() (вероятно, идентификатор в вашем случае), чтобы гарантировать, что один документ будет атомарно изменен и возвращен.

+0

Благодарим вас за этот замечательный ответ! Я бы поднял его дважды, если это возможно. Я, наконец, понимаю 'flush()' и 'merge()'. Хороший вызов о 'equals()' тоже. Я забыл включить это в мой надуманный пример. –

Смежные вопросы