【问题标题】:doctrine ODM (mongodb) merge doesn't work学说 ODM(mongodb)合并不起作用
【发布时间】:2012-05-31 06:09:47
【问题描述】:

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

【问题讨论】:

    标签: php mongodb doctrine doctrine-odm


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 感谢您的精彩回答!如果可能的话,我会投票两次。我终于明白flush()merge()。关于equals() 的电话也很好。我忘了在我的人为示例中包含它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2016-08-27
    • 2012-07-11
    • 1970-01-01
    • 2014-08-05
    相关资源
    最近更新 更多