0

我没有任何运气使用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()看起来很简单,所以我很困惑为什么它不像我认为的那样工作。

4

1 回答 1

3

在您的第一个代码示例中,merge()后跟persist()是多余的,并且您省略了 a flush(),这是实际写入数据库的唯一操作(除非您手动执行查询,就像您在第二个示例中所做的那样)。如果您浏览 中的代码UnitOfWork::doMerge(),您会看到它要么保留对象(如果它没有 ID),要么通过其 ID 获取文档。最终结果是merge()返回一个托管文档。Persist 确保文档在被调用后被管理(它本身不返回任何内容)。如果您深入UnitOfWork::doPersist()了解,您会发现将托管对象传递给该方法实际上是一个 NOOP。

尝试替换persist()flush(). 请注意,如果需要,您可以刷新单个文档,但$dm->flush()默认情况下会处理所有托管对象。

如果这仍然没有帮助,我会确认该lastUpdated字段已在 ODM 中正确映射。您可以检查输出$dm->getClassMetadata('MyDocumentClass')以确认。如果它不是映射字段,UnitOfWork 将检测到文档中没有任何更改,并且不会刷新任何内容。

顺便说一句:在第二个代码示例中,您在findAndUpdate()没有任何搜索条件的情况下执行(仅set()指定了 )。通常,您会将修改与类似的东西equals()(可能是您的 ID)配对,以确保单个文档被原子修改并返回。

于 2012-05-31T15:10:09.663 回答