Checking for duplicate keys with Doctrine 2

Viewed 46780

Is there an easy way to check for duplicate keys with Doctrine 2 before doing a flush?

9 Answers

I have come across this problem some time ago, too. The main problem is not database specific exceptions but the fact, when an PDOException is thrown the EntityManager is closed. That means you can not be sure what will happen with the data you wanted to flush. But probably it would be not saved in database because I think this is done within a transaction.

So when I was thinking about this problem I came up with this solution, but I did not have time to actually write it yet.

  1. It could be done using event listeners, particularly the onFlush event. This event is invoked before the data is send to database (after the changesets are computed - so you already know which entities were changed).
  2. In this event listener you would have to browse all the changed entities for their keys (for primary it would be looking in the class metadata for @Id).
  3. Then you would have to use a find method with the criteria of your keys. If you would find a result, you have the chance to throw your own exception, which will not close the EntityManager and you are able to catch it in your model and make some corrections to the data before trying the flush again.

The problem with this solution would be that it could generate quite a lot of queries to the database, so it would require quite a lot of optimization. If you want to use such thing only in few places I recommend doing the check on the place where the duplicate might arise. So for example where you want to create an entity and save it:

$user = new User('login');
$presentUsers = $em->getRepository('MyProject\Domain\User')->findBy(array('login' => 'login'));
if (count($presentUsers)>0) {
    // this login is already taken (throw exception)
}
Related