Unikt index med Doctrine och Symfony2
Symfony2 är ett utmärkt verktyg på många sätt men det är inte felfritt. Just nu sitter jag i slutfasen av ett större projekt som jag började med för snart ett år sedan. Det känns skönt att kunna se mållinjen.
Idag har hittade jag en betydelsefull bugg i dokumentationen. Det handlar om att sätta unika index på entities. Jag satt en timme och kliade mig i håret innan jag förstod att dokumentationen inte stämde och jag hade en lösning på problemet. Det lättaste sättet att sätta ett unikt index på en kolumn är att skriva så här:
class Author
{
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
protected $name;
Svårare än så är det inte. Vill man sätta ett unikt index över flera kolumner så föreslår dokumentationen att man skriver:
// Acme/UserBundle/Entity/User.php
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @UniqueEntity({"name","email"})
*/
class Author
{
/**
* @var string $email
*
* @ORM\Column(name="email", type="string", length=255, unique=true)
* @Assert\Email()
*/
protected $email;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
protected $name;
// ...
}
Men detta fungerar tyvärr inte. Detta ger två unika index över en kolumn. Vi ville ju ha ett unikt index över två kolumner. Efter lite grävande i Symfony2 källkoden så hittade jag en lösning. Man får använda table-argumentet uniqueConstraints. Följande kod ger mig det jag vill ha:
// Acme/UserBundle/Entity/User.php
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"name","email"},name="myUniqueIndex")})
*/
class Author
{
/**
* @var string $email
*
* @ORM\Column(name="email", type="string", length=255)
* @Assert\Email()
*/
protected $email;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255)
*/
protected $name;
// ...
}
Ingen bugg i ramverket men i dokumentationen. Jag hoppas denna bloggpost hjälper någon med samma problem.
Relaterat:
- MySQL-index gör skillnad
- WordPress, Symfony2 och Nginx
- Sökmotorerna fuskblåser upp sitt index
- Order by Rand() i Symfony2
- Symfony2 och Nginx




