Featured image of post Doctrine2で日付を更新できないパターン

Doctrine2で日付を更新できないパターン

Twitter ツイート Hatena Bookmark ブックマーク

Symfony2とDoctrine2で開発しているんですがたまにはまるパターンが・・・。 Doctrine2 ORMで日付を更新しようとしたのに更新されない事がありました。

問題のコードは以下のような感じ。 コントローラで適当にエンティティマネージャ呼び出して日付を更新する見たいな感じです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php

class TestController extends Controller
    public function updateAction(Article $article)
    {
        $em = $this->getDoctrine()->getManager();
        $post = $em->getRepository('MatterCoreBundle:Article')
                    ->find(1);
        $date = $post->getUpdatedAt()
        $date->setTimestamp(time());
        $post->setDate($date);
        $em->persist($post);
        $em->flush();
     }

コードをみればわかるとおもうんですが、日付を更新したいわけですよ。
(まあ、普段だったらTimestampable使うのでこんなコード書かないんですけどねw

で、この場合日付を変わっている物のオブジェクトが変わっていないようで、更新されないぽいです。 以下のように書き直すと更新されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
class TestController extends Controller
{
    public function updateAction(Article $article)
    {
        $em = $this->getDoctrine()->getManager();
        $post = $em->getRepository('MatterCoreBundle:Article')
                    ->find(1);
        $post->setDate(new \DateTime())
        $em->persist($post);
        $em->flush();
     }
}

中のコードまでは追っていませんが、どうやらDoctrineの更新条件がオブジェクト自体が変わったか変わってないかで判定しているっぽいですね。

ちなみにオブジェクト型でも同様の現象が発生するようです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?php

class TestController extends Controller
{
    public function updateAction(Article $article)
    {
        $em = $this->getDoctrine()->getManager();
        $post = $em->getRepository('MatterCoreBundle:Article')
                    ->find(1);
        $object = $post->getObject()
        $object->point += mt_rand(1,10000);
        $post->setObject($object);
        $em->persist($post);
        $em->flush();
     }
}

これだとオブジェクト自体は保存されません。。。 やはりもう一度オブジェクトを生成しないとだめみたいです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php

class TestController extends Controller
{
    public function updateAction(Article $article)
    {
        $em = $this->getDoctrine()->getManager();
        $post = $em->getRepository('MatterCoreBundle:Article')
                    ->find(1);
        $object = $post->getObject()
        $object = clone $object;
        $object->point += mt_rand(1,10000);
        $post->setObject($object);
        $em->persist($post);
        $em->flush();
     }
}

ということで、オブジェクトをEntityで扱う時は気をつけましょう。

comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。