Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine2 ORM doesn't refresh objects that are altered outside of a script

I really didn't know how to title this or search for an already posted question, so my apologies if this has been seen on here before.

I am getting some undesired results with the following code:

// get object managers
$fooManager = $this->getContainer()->get('foo_manager');
$barManager = $this->getContainer()->get('bar_manager');

// infinite loop
for (;;) {

    // keep getting unitialized "foo" objects, or quit if none
    while (($foo = $fooManager->findUninitialized()) !== null) {

        // an uninitialized "foo" will need to make a "bar" object
        $bar = $barManager->create();
        $bar->setA('...');

        // save "bar" to database, update() WILL perform a flush()
        $barManager->update($bar);

        // make the association of "bar" to "foo"
        $foo->setBar($bar);

        // save "foo" to database, update() WILL perform a flush()
        $fooManager->update($foo);

    }

    // keep getting unprocessed "foo" objects, or quit if none
    while (($foo = $fooManager->findUnprocessed()) !== null) {

        // process the data from "foo" object's "bar"
        process($foo->getBar()->getB());

    }

}

You can see that in the first while loop, $bar objects are being made and put into the database. Another script is picking up on these and doing things to them.

In the second while loop, the $foo objects are trying to access their modified "bar" object (notice the getB() being called, we can assume that in another script being executed separately setB() was used to change the state of the object).

However, in the second loop, when I call getB(), it is not returning the value I set with setB() in that other script.

I can ensure all of the data is being properly persisted (and flushed) to the database, so when the getB() is called in that second loop, whatever was holding "B" was changed and is present in the database.

One thing I've noticed is that in the log file, I am not seeing a query to pull in the data for "bar" when I call $foo->getBar() in the second loop (these should be lazily loaded). Also, if I var_dump() the value returned from $foo->getBar() in the second loop, it looks exactly like the associated "bar" object would look by the end of the first loop.

I'm thinking that there is some kind of caching or something going on (since I've altered those "bar" objects earlier in the script execution, Doctrine seems like it is just re-using those rather than reloading their data from the database).

I know what I am trying to do is probably not common. What I am doing is using the Symfony2 console command features to write a few command-line "daemons" to help with processing some data; the "daemon" that contains this code is being run in conjunction with another "daemon" that processes those "bar" objects that get created.

Curious as to whether there is a way to fix this to where in my second loop when I call the $foo->getBar() method, I am actually pulling the updated data from the database. Any help is greatly appreciated.

like image 361
jzimmerman2011 Avatar asked Feb 04 '13 00:02

jzimmerman2011


1 Answers

This was really provided by the user ChocoDeveloper. Making use of the refresh($entity) method on the entity manager solved my problem.

For example:

$em->refresh($entity);
like image 98
jzimmerman2011 Avatar answered Oct 17 '22 22:10

jzimmerman2011