Contraintes uniques dans la Doctrine 2, Symfony 2

Je veux faire une contrainte unique dans mon entité Doctrine 2 telle que name & test sont colonne unique Sage. Signification

  • Obj1

    • nom: nom1
    • test: test
  • Obj2

    • nom: nom2
    • test: test

Cela devrait déclencher une erreur car le test est dupliqué.

J'ai essayé d'utiliser la contrainte unique (SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity). Essayé

 * @UniqueEntity("name")
 * @UniqueEntity("test")

Et

 * @UniqueEntity({"name", "test"})

Les deux semblent ne déclencher une erreur que lorsque le nom et le test sont dupliqués. par exemple.

  • Obj1

    • nom: nom1
    • test: test
  • Obj2

    • nom: nom2
    • test: test

Quelle est la bonne configuration? Ou j'aurais pu faire une erreur quelque part?

Peut-être que je devrais inclure l'annotation de doctrine comme:

@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})

Mais cela ne gérera toujours pas ma forme symfony validation je pense?

Mise à JOUR

Mon code de test:

/**
 * @ORMEntity
 * @ORMTable(name="roles") 
 * @UniqueEntity("name")
 * @UniqueEntity("test")
 */
class Role {

    /**
     * @var integer
     * @ORMColumn(type="integer")
     * @ORMId
     * @ORMGeneratedValue
     */
    protected $id;

    /**
     * @var string
     * 
     * @ORMColumn(type="string", length=32, unique=true)
     * @AssertMaxLength(32)
     * @AssertRegex("/^[a-zA-Z0-9_]+$/")
     */
    protected $name;

}

$v = $this->get('validator');

$role = new Role();
$role->setName('jm');
$role->setTest('test');
$e = $v->validate($role);
echo '=== 1 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role);            

$role2 = new Role();
$role2->setName('john');
$role2->setTest('test');
$e = $v->validate($role2);
echo '=== 2 ===';
var_dump($e);
if (count($e) == 0)
    $em->persist($role2);

$em->flush();

Lors de la première exécution (table vide):

=== 1 ===object(SymfonyComponentValidatorConstraintViolationList)#322 (1) {
  ["violations":protected]=>
  array(0) {
  }
}
=== 2 ===object(SymfonyComponentValidatorConstraintViolationList)#289 (1) {
  ["violations":protected]=>
  array(0) {
  }
}

Mais je reçois une erreur sur la couche de base de données à propos de la contrainte unique. Alors, comment dois-je faire fonctionner la couche de Validation?

27
demandé sur Jiew Meng 2011-12-17 18:59:28

2 réponses

Ceux-ci vérifient les champs individuellement:

@UniqueEntity("name")
@UniqueEntity("test")

C'est-à-dire que le premier sera déclenché lorsqu'il y a une valeur name en double, tandis que le second-lorsqu'il y a une valeur test en double.

Si vous voulez l'échec de validation lors de la les deux name et test contiennent le même combinaison, vous utilisez:

@UniqueEntity({"name", "test"})

Pour ce que vous voulez, la première approche devrait fonctionner - à moins que vous n'ayez fait quelque chose de mal ailleurs. Essayez également d'effacer le cache pour assurez-vous qu'il n'est pas de sa faute.

Mise à JOUR

Ce que j'ai suggéré concernait la partie validation du côté de l'application. Si vous générez le schéma de base de données à L'aide de Doctrine, vous devrez fournir les annotations de niveau Doctrine pour chaque colonne - si vous voulez les rendre uniques indépendamment les unes des autres, bien sûr:

@Column(type = "string", unique = true)
private $name;

@Column(type = "string", unique = true)
private $test;

Ces approches se complètent - pas exclure. @UniqueEntity s'assure qu'un doublon n'atteint même pas la couche de base de données, alors que @Column garantit que si c'est le cas, la couche de base de données ne le laissera pas passer.

50
répondu Elnur Abdurrakhimov 2011-12-17 15:33:41

Dans l'annotation de Table, vous pouvez également définir un index pour plusieurs colonnes .

/**
 * @ORM\Entity
 * @ORM\Table(name="ecommerce_products",uniqueConstraints={
 *     @ORM\UniqueConstraint(name="search_idx", columns={"name", "email"})})
 */

Ou au format YAML:

Namespace\Entity\EntityName:
    type: entity
    table: ecommerce_products
    uniqueConstraints:
        uniqueConstraint:
            columns: [name, email]
49
répondu yvoyer 2014-12-19 14:27:59