2017年9月19日火曜日

postPersist内でpersist()とflush()を呼びたい時の無限再帰を止める方法

イベントリスナーのpostPersist内でEntityManagerがpersist()とflush()を呼ぶと、そのためにイベントリスナーのpostPersistが呼ばるため、無限の再帰となりOutOfMemoryException等が発生する。もし、イベントリスナー内で登録したいEntityクラスがあらゆる場所でそのイベントリスナーを呼ぶ必要がない場合には、無限の再帰を止める方法がある。
use Doctrine\ORM\Event\LifecycleEventArgs;

class EventListener
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        if($entity instanceof Only\In\Listener\Entity) return;
        $entityManager = $args->getEntityManager();
        $entity = new Only\In\Listener\Entity();
        //...
        $entityManager->persist($entity);
        $entityManager->flush();
    }
}
イベントリスナー内で登録されるEntityクラスの登録がイベントの発生源となった場合に、instanceofで判定し、returnすれば良い。

0 件のコメント:

コメントを投稿