Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine update entity in loop, persist or flush?

I have multiple loops like :

    $bets = $this->em->getRepository('AppBundle:Bet')->getBetsForMatch($match_id);

    foreach ($bets as $key => $bet) {
        $devices = $this->em->getRepository('AppBundle:Device')->findBy(array('user' => $bets->getUser()));

        foreach ($devices as $key => $device) {
            //HERE I SEND A PUSH NOTIFICATION

            if($this->rms_push->send($message)){
                $device->getUser()->setBadge($device->getUser()->getBadge() + 1);
                $this->em->flush();
            }
        }
    }

So, I get all bets for a match, for each bet I get all devices saved for the user, and after that I need to update my user with : $device->getUser()->setBadge($device->getUser()->getBadge() + 1);

For now, I flush each time but I think there is a better way, ideas ?

like image 377
Clément Andraud Avatar asked Mar 16 '16 15:03

Clément Andraud


1 Answers

You need only one flush, out of your loop:

foreach ($bets as $key => $bet) {
    $devices = $this->em->getRepository('AppBundle:Device')->findBy(array('user' => $bets->getUser()));

    foreach ($devices as $key => $device) {
        //HERE I SEND A PUSH NOTIFICATION

        if($this->rms_push->send($message)){
            $device->getUser()->setBadge($device->getUser()->getBadge() + 1);
        }
    }
}

$this->em->flush();

Calling $this->_em->persist($obj) involves to create a new entry.

If you need to create or update depending on the entry exists or not, look at EntityManager::merge .

To preserve memory usage for large number of entries, look at batch processing.

Note SensioLabs insight (PHP source code quality analysis) raises a warning if your code calls EntityManager::flush inside a loop.

like image 181
chalasr Avatar answered Sep 20 '22 00:09

chalasr