josef.van.niekerk
josef.van.niekerk

Reputation: 12121

Why is my Symfony2 @UniqueEntity constraint not working at all?

I have the following entity class in my application:

<?php

namespace ...;

// use ...
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;;
// ...

/**
 * @ORM\Table(name="sc_user")
 * @ORM\Entity(repositoryClass="...\UserRepository")
 * @ORM\HasLifecycleCallbacks()
 * @UniqueEntity(fields={"email", "username"})
 */
class User implements UserInterface, \Serializable, EquatableInterface
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $email
     *
     * @ORM\Column(name="email", type="string", length=255, unique=true)
     *
     * @Assert\NotBlank(groups={"registration"})
     * @Assert\Email(groups={"registration"})
     */
    private $email;

    /**
     * @var string $username
     *
     * @ORM\Column(name="username", type="string", length=32, unique=true)
     *
     * @Assert\NotBlank(groups={"registration"})
     */
    private $username;

    // ...
}

The @UniqueEntity constraint is being ignored. I tried different flavors including:

@UniqueEntity(fields={"email", "username"})

and

@UniqueEntity(fields={"email"})
@UniqueEntity(fields={"username"})

and, as per the Symfony2 documentation here: http://symfony.com/doc/current/reference/constraints/UniqueEntity.html

@UniqueEntity("email")
@UniqueEntity("username")

Nothing I do, works. Instead of getting a form validation error as expected, I am getting the following exception:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '[email protected]' for key 'UNIQ_D8183973E7927C74'

This is just wrong! Does anyone know how to fix this issue?

Upvotes: 10

Views: 20731

Answers (4)

stollr
stollr

Reputation: 7183

Another reason for this issue is if you are using form collections and include a sub-form which handles an associated entity, you have to set cascade_validation to true in the root and all sub-forms.

See the hint in the Symfony documentation:

To activate validation on CategoryType, add the cascade_validation option to TaskType:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Acme\TaskBundle\Entity\Task',
        'cascade_validation' => true,
    ));
}

Update:

To ensure that your child entities are validated there is even a better way. Symfony provides the Valid constraint for exactly this reason. From documentation:

Valid
This constraint is used to enable validation on objects that are embedded as properties on an object being validated. This allows you to validate an object and all sub-objects associated with it.

Upvotes: 14

nvvetal
nvvetal

Reputation: 1793

Please note ignoreNull

For example to work correctly with pid (can be null):

constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
  fields: [page, pid, position]
  errorPath: page
  groups: [Menu]
  message: "Page already exists with that parent"
  ignoreNull: false

Upvotes: 4

josef.van.niekerk
josef.van.niekerk

Reputation: 12121

The problem was solved as follows:

@UniqueEntity(fields={"email"}, groups={"registration"})
@UniqueEntity(fields={"username"}, groups={"registration"})

The registration groups were missing, and I needed to separate them into two separate annotations.

Upvotes: 25

AdrienBrault
AdrienBrault

Reputation: 7745

Try to add

framework:
    validation:
        enable_annotations: true

to your app configuration

Upvotes: 2

Related Questions