我使用merge()
没有运气。我几乎正好what is documented:
/* @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()
看起来很简单,所以我很困惑为什么它不能像我认为的那样工作。
答案 0 :(得分:3)
在您的第一个代码示例中,merge()
后跟persist()
是多余的,您省略了flush()
,这是实际写入数据库的唯一操作(除非您执行手动查询,就像在第二个例子中所做的那样)。如果您浏览UnitOfWork::doMerge()
中的代码,您将看到它将持久保存对象(如果它没有ID)或通过其ID获取文档。最终结果是merge()
返回托管文档。 Persist确保文档在被调用后将被管理(它本身不返回任何内容)。如果您查看UnitOfWork::doPersist()
,您会看到将托管对象传递给该方法实际上是一个NOOP。
尝试将persist()
替换为flush()
。请注意,您可以根据需要刷新单个文档,但默认情况下$dm->flush()
会处理所有托管对象。
如果仍然无效,我会确认{O}中的lastUpdated
字段已正确映射。您可以检查$dm->getClassMetadata('MyDocumentClass')
的输出以进行确认。如果它不是映射字段,UnitOfWork将检测到文档中没有任何更改,并且没有任何内容可以刷新。
顺便说一下:在第二个代码示例中,您正在执行findAndUpdate()
而没有任何搜索条件(仅指定了set()
)。通常,您将修改与equals()
(可能是您的ID中的ID)配对,以确保单个文档被原子修改并返回。