Doctrine Entity increase value (Download counter)

doctrine, doctrine-orm, php, symfony

Solution

You can also do the following in an entity repository:

return $this
    ->createQueryBuilder('f')
    ->update($this->getEntityName(), 'f')
    ->set('f.downloadCounter', $file->getDownloadCounter() + 1)
    ->where('f.id = :id')->setParameter('id', $file->getId())
    ->getQuery()
    ->execute();

Or using DQL:

 $em = $this->getDoctrine()->getManager();
 $query = $em->createQuery(
     'UPDATE YourBundle:File f
      SET f.downloadCounter = :downloadCounter'
 )->setParameter('downloadCounter', $file->getDownloadCounter() + 1);

Or through a simplified DQL:

 $em = $this->getDoctrine()->getManager();
 $query = $em->createQuery(
     'UPDATE YourBundle:File f
      SET f.downloadCounter = f.downloadCounter + 1'
 );

The drawback with these solutions: if your entity was already loaded it will have the previous count and not the incremented count.

The way you did is perfectly fine but a better way is to add an increment method to your entity.

Follow-up from Radu C comment below: the simplified DQL is the only solution that guarantees proper count.

The query increments based on the value in the database and locks the table guaranteeing queries to be executed in a sequence.

Whereas the other queries use the value in PHP runtime which may be an outdated value: some other request may have already incremented the value in the database therefore incrementing based on value in PHP memory will override increment made by other requests.

Problem

I want to increase a value in my doctrine entity. Currently I'm doing it this way. ``` $file->setDownloadCounter($file->getDownloadCounter() + 1); $em = $this->getDoctrine()->getManager(); $em->persist($fileVersion); $em->flush(); ``` Is there way to execute something like this in doctrine: ``` UPDATE file SET downloadCounter = downloadCounter + 1 WHERE id = 1 ``` EDIT: The problem in the doctrine example above is that between loading and flush is time where others could download the file and so the counter is not correct.

Original source