IMHO you should check for duplicates _before_ persisting/flushing. This will save you the time/resources of creating those entities in the first place.
Secondly, even if you query the db just before an entity is stored, you still have a (verry narrow) window in which another request could store the same thing, and still hit a unique constraint violation. So catching the PDO exception is the only reliable way to prevent this. PS: You could start a transaction manually [1], and _clear_ the EntityManager in stead of closing it when an exception is thrown, so you can continue using it. Though IMO there rarely is a case where the EntityManager shouldn't be closed (these kind of things should be reported back to the user). [1]: https://doctrine-orm.readthedocs.org/en/latest/reference/transactions-and-concurrency.html -- Jasper N. Brouwer (@jaspernbrouwer) On 12 June 2014 at 12:04:12, James ([email protected]) wrote: > Hi, > > I'm trying to find an efficient and reliable way to check for duplicate > entities when persisting/ flushing. > > In previous projects where I didn't use Doctrine associations, I used to > just check the single entity before it was persisted, using the entity > metadata to find duplicates based on the unique constraints. > > However, now I have switched to use associations correctly, which means I > could have many depths of nested entities. I don't want to recursively loop > through each entity and it's children before querying the repository for > each entity found. > > I understand that Doctrine provides no duplicate key checking, so I'm > interested to see what solutions others have to the problem. > > One thing I did try was to use a prePersist lifecycle event to check > constraints before the persist is fulfilled: > > /** > * @param DoctrineORMEventOnFlushEventArgs $eventArgs > * @return void > */ > public function prePersist(Doctrine\ORM\Event\LifecycleEventArgs > $eventArgs) > { > $entityManager = $eventArgs->getEntityManager(); > $entity = $eventArgs->getEntity(); > > if (null === $entity->getId()) { > > // findExistingEntity searches the repository using the unique > constraints > $existing = $this->findExistingEntity($entity, $entityManager); > > if (null !== $existing) { > $entityManager->merge($existing); > } > } else { > $entityManager->merge($existing); > } > // continue with persist > } > Of course this does not work as it will result in an infinite loop, but > hopefully it shows what I'm getting at. Is there a way I can adjust the > operation during persist like this? If not, I'd greatly appreciate > suggestions! I know a lot of people catch the PDOException thrown, but I > don't like the idea of having to create a new EntityManager every time a > constraint is violated. > > Thanks! -- You received this message because you are subscribed to the Google Groups "doctrine-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/doctrine-user. For more options, visit https://groups.google.com/d/optout.
