Skip to content

Commit

Permalink
[Doctrine] Fix UniqueEntityValidator reporting a false positive by ig…
Browse files Browse the repository at this point in the history
…noring multiple query results

An entity should only be considered unique if its search criteria returns no matches or a single, identical entity. Multiple results indicates that conflicting entities exist.
  • Loading branch information
jmikola committed Sep 1, 2011
1 parent 7cb402d commit d19f1d7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
Expand Up @@ -75,13 +75,19 @@ public function isValid($entity, Constraint $constraint)
$repository = $em->getRepository($className);
$result = $repository->findBy($criteria);

if (count($result) > 0 && $result[0] !== $entity) {
$oldPath = $this->context->getPropertyPath();
$this->context->setPropertyPath( empty($oldPath) ? $fields[0] : $oldPath.".".$fields[0]);
$this->context->addViolation($constraint->message, array(), $criteria[$fields[0]]);
$this->context->setPropertyPath($oldPath);
/* If no entity matched the query criteria or a single entity matched,
* which is the same as the entity being validated, the criteria is
* unique.
*/
if (0 == count($result) || (1 == count($result) && $entity === $result[0])) {
return true;
}

$oldPath = $this->context->getPropertyPath();
$this->context->setPropertyPath( empty($oldPath) ? $fields[0] : $oldPath.".".$fields[0]);
$this->context->addViolation($constraint->message, array(), $criteria[$fields[0]]);
$this->context->setPropertyPath($oldPath);

return true; // all true, we added the violation already!
}
}
Expand Up @@ -129,4 +129,25 @@ public function testValidateUniquenessWithNull()
$violationsList = $validator->validate($entity1);
$this->assertEquals(0, $violationsList->count(), "No violations found on entity having a null value.");
}

public function testValidateUniquenessAfterConsideringMultipleQueryResults()
{
$entityManagerName = "foo";
$em = $this->createTestEntityManager();
$this->createSchema($em);
$validator = $this->createValidator($entityManagerName, $em);

$entity1 = new SingleIdentEntity(1, 'foo');
$entity2 = new SingleIdentEntity(2, 'foo');

$em->persist($entity1);
$em->persist($entity2);
$em->flush();

$violationsList = $validator->validate($entity1);
$this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.');

$violationsList = $validator->validate($entity2);
$this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.');
}
}

0 comments on commit d19f1d7

Please sign in to comment.