在一个巨大的数据集中,当删除一个文档时,我有时会出现不一致的情况。使用Doctrine ODM和FosREST的Symfony2应用程序
$a = new Element();
$b = new Element();
$c = new List();
$c->addElement($a);
$c->addElement($b);
$em->persist($c);
此时保存完美无缺
在99%的情况下,$ a和$ b仍然是有效的文件,以后加载$ c。 但有时会删除$ a或$ b而不更新$ c中的引用。
- >此时$ c的下一次加载将失败并出现\ Doctrine \ ODM \ MongoDB \ DocumentNotFoundException
(消息类似于:" MongoDBODMProxies__CG __ \ App \ Model \ Element"文档带有标识符" 541417702798711d2900607c"找不到。)
现在处理这种情况的最佳方法是什么?
我在考虑
更新:文档之间的映射比我在此处描述的要复杂一些
答案 0 :(得分:1)
要检查MongoDB的一些事项:
确保没有循环引用(例如,如果类List上有属性$ elements,并且引用设置为true,请确保在Elements类中未引用List)和你的映射是一致的。
在addElement函数中,如果引用保存在Element类上,请确保在函数内部也调用$ element-> setList($ this)。 (对于removeElement也一样,如果需要,取消设置引用)
确保您级联所有必要的操作。 (例如级联:[“持久”,“删除”,“刷新”或“全部”]
您可以使用
检查映射$ app/console doctrine:mongodb:mapping:info
最后,如果您希望删除该文档,但是从代理对象收到错误,则可以清除元数据缓存
$ app/console doctrine:mongodb:cache:clear-metadata
答案 1 :(得分:1)
目前无效的解决方案
我现在选择抛出一个新的Exception(重要的是不要让doctrine抛出一个,因为它会拒绝同一个请求中的任何持久尝试)。
在PostLoad LifecycleEvent中,我现在检查以下内容(简化):
if ($document instanceof List) {
foreach ($document->getElements() as $element) {
// at this moment $element->getId() is already defined but not yet loaded from mongo
$result = $this->elementRepository->findBy(array(‘_id’ => $element->getId()));
if (sizeof($result)==0) {
throw new InvalidElementInList($element->getId());
}
}
}
在RestController中,这使我能够捕获这个特定的异常,并从列表中删除无效元素+,向用户返回一个自定义视图,表明该元素已被删除。