Symfony2 UniqueEntity not working: throws db exception

1.4k views Asked by At

I have a User class as follows:

/**
* User
*
* @ORM\Table()
* @ORM\Entity
* @UniqueEntity("username")
*/
class User implements UserInterface
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="username", type="string", length=30, unique=true)
 */
private $username;
...

As you guessed, I want to maintain usernames unique. When I try to register a new user which duplicates a previous username, I get a db exception:

An exception occurred while executing 'INSERT INTO User (username, hashedpassword, email) VALUES (?, ?, ?)' with params ["xx", "$2y$10$7rrY0tw0eG8ui7hRkpGI..8Wf16DP1fQMLymaOmHnbZsBw6M1uY.i", "[email protected]"]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'xx' for key 'UNIQ_2DA17977F85E0677' 

I thought that perhaps the problem is in my Registration Controller. I'm using the one given on

http://symfony.com/doc/current/cookbook/doctrine/registration_form.html

The relevant bits:

class AccountController extends Controller
{
public function registerAction()
{
    $registration = new Registration();
    $form = $this->createForm(new RegistrationType(), $registration, array(
        'action' => $this->generateUrl('account_create'),
    ));

    return $this->render(
        'RezialRezialBundle:Account:register.html.twig',
        array('form' => $form->createView())
    );
}


public function createAction(Request $request)
{
$em = $this->getDoctrine()->getManager();

$form = $this->createForm(new RegistrationType(), new Registration());

$form->handleRequest($request);

if ($form->isValid()) {
    $registration = $form->getData();

    //should I manually check for unicity here?


    $em->persist($registration->getUser());
    $em->flush();

    //The following 3 lines make the user automatically login
    //upon successfull registration!
    $user = $registration->getUser();
    $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
    $this->get('security.token_storage')->setToken($token);

    return $this->redirectToRoute('homepage');
}

return $this->render(
    'RezialRezialBundle:Account:register.html.twig',
    array('form' => $form->createView())
);
}

}

Any ideas on what's missing?

2

There are 2 answers

2
Geoffroy On BEST ANSWER

Didn't you forget the @Assert\Valid() annotation on the $user property of the Registration class?

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.

link: Valid Constraint Documentation

0
BentCoder On

Try this:

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

/**
 * @ORM\Entity
 * @ORM\Table(name="user")
 * @UniqueEntity(fields="username", message="Username is already taken.")
 */
class User
{
    /**
     * @ORM\Column(name="username", type="string", length=30, unique=true)
     */
    protected $username;
}