1
votes

I have a Repository Like Bellow.

The code checks first if the item is already in the table.

  • If it is not it downloads the data and then stores it to the table.

  • If it is already in the table it just returns the record.

But sometimes after it checks for the item in the table it will still go and try to download and store the item even though it is already there, creating a key conflict, but this should never happen since it just searched and did not find it.

Things to note:

  1. If I disable $query->useResultCache(true) i have no problem.
  2. This is the only process working on the table.
  3. This is the only place in code that items are added to the table.
  4. This code is being called from a symfony2 console command.
  5. Memcache is the set cache for doctrine2.
  6. Memcached is running locally.
  7. The error is produced when using arraycache as well.
  8. This query is run many times a second.
    class ItemRepository extends EntityRepository
    {
      public function findOrFetch($id)
      {

        $item = $this->findItem($id);

        if($item != null)
          return $item;
        else
          {
        $itemData = $this->fetchItem($id);

        $item = new Item();
        $item->setId($id);
        $item->setName($itemData['name']);
        $this->getEntityManager()->persist($item);
        $this->getEntityManager()->flush();
          }
      }

      private function findItem($id)
      {
        $query = $this
          ->getEntityManager()
          ->createQuery('SELECT i from MonkeyWire\WowProfToolsBundle\Entity\Item i WHERE i.id = ?1');
        $query->setParameter(1, $id);
        $query->useResultCache(true);

        return $query->getOneOrNullResult();
      }

      private function fetchItem($id)
      {
        $api = new Client();
        $api->setRequest(new Curl());

        try
          {
        $itemData = $api->getItemsApi()->getItem($id);
          }
        catch (NotFoundException $e)
          {
        $itemData['name'] = "na";
          }

        return $itemData;
      }
    }
1

1 Answers

0
votes

It sounds like you may need to expire the result cache when you add a new item.

$query->expireResultCache();

Based on your Repository you may need to do some restructuring to accommodate that though:

class ItemRepository extends EntityRepository
{
    public $findQuery = null;
    ...
    public function findOrFetch($id)
    {
        ...
        $this->getEntityManager()->flush();
        $this->findQuery->expireResultCache();
          }
    }

    private function findItem($id)
    {
      $query = $this
        ->getEntityManager()
        ->createQuery('SELECT i from MonkeyWire\WowProfToolsBundle\Entity\Item i WHERE i.id = ?1');
      $query->setParameter(1, $id);
      $this->findQuery = $query;
      ...
    }
}