Symfony2とDoctrine2を使っているあるシステムにおいて、
日付の更新処理でハマったのでメモ。
ある処理を行ったら、
有効期限を1年延長する、という処理を以下のコードで実装しようとしました。
NGHoge.php
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository(Hoge::class)->find($id)
$expiryAt = $entity->getExpiryAt()->modify('+1 years');
$entity->setExpiryAt($expiryAt);
$em->flush();
上記のコードを実行したところ、
DBに保持されている有効期限はそのままで更新されていませんでした。
調べてみると、Doctrineはオブジェクトが同じ参照だと
更新しないようです。
$entityのgetExpiryAt()はDateTime型のオブジェクトを返します。
そのため同じオブジェクトのDateTimeに+1年してもデータが変更されなかったようです。
ですので以下のコードに変更しました。
OKHoge.php
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository(Hoge::class)->find($id)
$expiryAt = (clone $entity->getExpiryAt())->modify('+1 years'); // ★この行を変更
$entity->setExpiryAt($expiryAt);
$em->flush();
cloneして新しいオブジェクトを作るようにしました。
こうすることで更新されるようになりました。
オブジェクトをEntityにセットする箇所は注意が必要です。