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.

Reply via email to