-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
UniqueEntity failed to invalidate new collections with duplicate values #9848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
so we can make more reliable tests. With this change testValidateUniquenessAfterConsideringMultipleQueryResults fails as it is broken by design. It adds to database duplicate value.
1) Symfony\Bridge\Doctrine\Tests\Validator\Constraints\UniqueValidatorTest::testValidateUniqueness
Doctrine\Common\Annotations\AnnotationException: [Semantical Error] The class "Table" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "Table". If it is indeed no annotation, then you need to add @IgnoreAnnotation("Table") to the _class_ doc comment of class Symfony\Bridge\Doctrine\Tests\Fixtures\UniqueConstraintEntity. ? I don't get it, tests passes on my dev env. |
please add the standard table description for PRs found in the docu |
@cordoval Missing PR header is now detected by fabbot (see http://hook.fabbot.io/report/symfony/symfony/9848) |
@arvenil please address all issues on http://status.fabbot.io/symfony/symfony/9848 |
To fix the tests on Travis, use a namespace prefix: <?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="name", columns={"name"})})
*/
class UniqueConstraintEntity
{
/** @ORM\Id @ORM\Column(type="integer") */
protected $id;
/** @ORM\Column(type="string", nullable=true) */
public $name;
public function __construct($id, $name)
{
$this->id = $id;
$this->name = $name;
}
public function __toString()
{
return (string) $this->name;
}
} |
@@ -30,6 +30,11 @@ class UniqueEntityValidator extends ConstraintValidator | |||
private $registry; | |||
|
|||
/** | |||
* @var array | |||
*/ | |||
protected $collection = array(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Storing the currently persisted entities is the responsibility of the entity manager. Duplicating this here is 1) erroneous (is each entity persisted? What about deleted entities? etc.) and 2) a memory leak (we only add, but never remove entities from the collection).
I think the correct solution to the underlying problem is adding a new property /**
* @Collection(unique=true)
*/
private $discounts; in your model to activate validation. In a second step, we can add a validator metadata loader implementation that uses Doctrine's metadata as source and automatically adds this and other constraints (such as |
Thanks for hint! @bschussek
Well, that's basically why I was sure this shouldn't be fixed that way :) Just wanted to point out the problem, and that currently there is no way to fix that nicely. And what is a better way to do that than a PR? (well PR with proper solution, but I'm not so good with symfony yet :) )
Thanks for getting this further! Yes, the idea looks like proper way to fix that problem - as I thought this requires bigger design changes. However I don't feel like working on it - I'm not yet enough familiar with symfony to make such changes :) But I will watch the progress and probably test the final solution - one more time, thanks for addressing the problem! |
Basically I run over the same problem as described here:
http://stackoverflow.com/questions/11782056/how-to-validate-unique-entities-in-an-entity-collection-in-symfony2
In other words, if you have new entities collection and it contains at least two objects with same values on unique field then validator does nothing, allowing to proceed orm with inserting data which ends with "SQLSTATE[23000]: Integrity constraint violation".
The problem is that validator is unaware of collection as a whole, and it only validates against db.
So I thought I could try to fix even though problem is not trivial and solution I came with isn't great too (again, because validators are unaware of collection as a whole). But without it UniqueEntity is kinda useless right now.
The most important part is testValidateUniquenessForDuplicatesInCollection. However additionally I've changed tests to actually use entity with defined unique constraint, so test could be more reliable. Test testValidateUniquenessAfterConsideringMultipleQueryResults immediately failed after that change as it is broken by design. You can't persist record "foo" for field name twice if assumption was that field name is unique - so I fixed that test too.
Anyway, feel free to merge that as a whole, merge only some commits, change whatever need changes (or ask me to do that) or point me to completely different solution.
Todo: