doctrine ODM(mongodb)合并不起作用

时间:2012-05-31 06:09:48

标签: php mongodb doctrine doctrine-odm

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

1 个答案:

答案 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)配对,以确保单个文档被原子修改并返回。