Search code examples
symfonyentitymanagercreatequery

Symfony2 $em->createQuery() also selects removed objects


Foreword: My script is a bit complicated so I try to reduce the complexity down to a simple example.

Imagine we have an entity "company". We have also a repository-function that looks like this:

public function delete(){

    // get company-objects to delete
    [...]

    // delete some companies
    $this->getEntityManager()->remove($company1);
    $this->getEntityManager()->remove($company2);

    // do other things
    [...]

    // get companies via createQuery (I really need to do it via 
    // createQuery because of different reasons that would be too
    // complicated to explain for this problem)
    $query = $this->getEntityManager()
                    ->createQuery('
                        SELECT company
                        FROM MyOwnBundle:Company company
                        WHERE [...irrelevant...]
                    ');
    $companies = $query->getResult();
    dump($companies);
    exit;
}

The problem: The createQuery also selects the removed companies.

My thoughts:

  • I thought that the entityManager knows that the companies are removed and therefore doesn't select them in a query. But this thought was wrong... (But why is this? Isn't the entityManager a global singleton-object?)
  • I know that when I would persist the data with flush() before using createQuery the results would be fine. But I can't persist the data here because then the whole process wouldn't be in a transaction.
  • I also can't manipulate the where-part of createQuery to exclude the already deleted companies because the whole process is separated into many functions and it would be hard to transport an array with the removed companies through the whole process.

The Question: How can I get the companies via createQuery without the removed ones?


Solution

  • You could wrap your code like below to make your whole process be in a transaction. This way you could flush right after remove the data.

    $this->getEntityManager()->transactional(function($em) {
       // put your code here
       // $em is instanceof EntityManager
    });