【问题标题】:flush() doesn't update embed documentsflush() 不更新嵌入文档
【发布时间】:2014-11-16 05:56:25
【问题描述】:

我有这些课程:

class Country
{
    /**
     * @MongoDB\Id
     */
    protected $id;

    /**
     * @MongoDB\String
     */
    protected $iso;

    /**
     * @MongoDB\EmbedOne(targetDocument="Localstring")
     */
    protected $name;

    public function __construct(){
        $this->name = new Localstring();
    }
}

class Localstring
{
    /**
     * @MongoDB\Id
     */
    private $id;

    /**
     * @MongoDB\Hash
     */
    private $location = array();
}

我想用新的翻译更新每个国家:

$dm = $this->get('doctrine_mongodb')
    ->getManager();

foreach ($json as $iso => $name) {
    $country = $dm->getRepository('ExampleCountryBundle:Country')->findOneByIso($iso);

    $localstring_name = $country->getName();
    $localstring_name->addTranslation('es_ES', $name);

    $dm->flush();
}

如果我在冲洗之前打印一个对象,它会正确打印:

Example\CountryBundle\Document\Country Object ( [id:protected] => 541fe9c678f965b321241121 [iso:protected] => AF [name:protected] => Example\CountryBundle\Document\Localstring Object ( [id:Example\CountryBundle\Document\Localstring:private] => 541fe9c678f965b321241122 [location:Example\CountryBundle\Document\Localstring:private] => Array ( [en_EN] => Afghanistan [es_ES] => Afganistán ) ) )

但在数据库上它不会更新。我尝试更新 $iso 并且它有效。为什么会这样?

【问题讨论】:

    标签: mongodb symfony doctrine-orm embed flush


    【解决方案1】:

    你忘记持久化你的对象了。 flush() 只是将persist() 注册的更改推送到数据库中(在参数中使用您的对象调用)。它需要在这里,因为您不会更改文档。您刚刚添加了翻译。 Translatable 扩展涵盖了此功能,并且不会告诉 Doctrine 您的对象已被修改。而当 Doctrine 为查询准备更改列表时,它不会找到更改,也不会创建查询。

    您的代码应如下所示:

    $dm = $this->get('doctrine_mongodb')
        ->getManager();
    
    foreach ($json as $iso => $name) {
        $country = $dm->getRepository('ExampleCountryBundle:Country')->findOneByIso($iso);
    
        $localstring_name = $country->getName();
        $localstring_name->addTranslation('es_ES', $name);
    
        $dm->persist($country);
    }
    $dm->flush();
    

    【讨论】:

    • 这些对象以前存在于数据库中,这是一个更新操作。 DoctrineMongoDB 文档说 persist() 调用它是不需要的 (symfony.com/doc/current/bundles/DoctrineMongoDBBundle/…)。无论如何,我尝试了您的代码,但它不起作用。
    • 正如您在页面中看到的(来自您的链接)Recall that this method simply tells Doctrine to manage or "watch" the $product object。您的翻译扩展程序无法管理这种“观看”。因此它不会告诉 Doctrine 您的对象已更新。
    【解决方案2】:

    你忘记了持久化你的对象!

    在你的 foreach 结束时试试这个:$dm->persist($your_object);

    在foreach的外部表单中放$dm->flush();

    【讨论】:

    • 您的回答与我之前的回答相同。我认为重复答案不好;-)
    猜你喜欢
    • 2014-06-12
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 2013-06-12
    • 2011-12-21
    相关资源
    最近更新 更多