Reputation: 9269
I have an entity Key
(Not the real name, I know Key is forbidden) and I need, in a loop, get a Key
with state=1
, and change it to state=2
. This is my script :
/* Each object */
for ($i=0; $i < $order->getQuantity(); $i++) {
/* get available key */
$key = $this->getDoctrine()->getRepository('AppBundle:Key')->findOneBy(array('state' => 1));
$key->setState(2); // On la rend active
$this->_em()->persist($key);
}
}
My probleme is with this line : $key = $this->getDoctrine()->getRepository('AppBundle:Key')->findOneBy(array('state' => 1));
Doctrine always get the same first key with state=1
. If I flush directly in the loop it's ok, but I can have a very big loop and I don't want to flush XXXX times.
Is there a way to don't get already persisted entity ? How can I say to Doctrine to get a Key with
state=1
ONLY if I don't already persisted ?
Thanks !
Upvotes: 0
Views: 1637
Reputation: 1715
Persisting means "Hey Doctrine, let's be aware of that entity instance!".
It's used (as you surely already know) when you create a new entity instance ($key = new Key();
), and then you want Doctrine to be aware of it ($em->persist($key);
) to be able to add a new record in the database on flush ($em->flush()
).
All entity instances retrieved with Doctrine are already persisted (Doctrine is already aware of them).
So, in your code, the persist
call is useless. And as you don't flush, the database is not updated.
Then, in the next loop, when you request from the database (->findOneBy(...)
), you will get again the same entity instance, with state
still equals to 1.
Finally, to answer your questions "Is there a way to don't get already persisted entity ? How can I say to Doctrine to get a Key with state=1
ONLY if I don't already persisted ?":
No, it's just impossible.
Upvotes: 0
Reputation: 14136
In addition to retrieving and looping over your entities, you can also use DQL (unless I am missing context from your question that precludes this).
For example:
$dql = 'UPDATE AppBundle:Key k SET k.state = 2 WHERE k.state = 1';
$query = $this->_em->createQuery($dql);
$result = $query->getResult();
This is untested obviously. It's been a while since I wrote DQL so you might want to consult the docs. Hope this helps :)
Upvotes: 0
Reputation: 4835
Why don't you do this:
$keys = $this->getDoctrine()->getRepository('AppBundle:Key')->findBy(array('state' => 1));
foreach($keys as $key) {
$key->setState(2);
$this->_em()->persist($key);
}
$this->_em()->flush();
Thereby each key will only be persisted once and because persisting things is symfony logic only you have only one DB write action during the flush-function where all persisted items will be stored
Upvotes: 3