Coder Perfect

Doctrine and composite keys are both unique.

Problem

In doctrine, I’d like to do a composite unique key. Those are my specialties:

/**
 * @var string $videoDimension
 *
 * @Column(name="video_dimension", type="string", nullable=false)
 */
private $videoDimension;

/**
 * @var string $videoBitrate
 *
 * @Column(name="video_bitrate", type="string", nullable=false)
 */
private $videoBitrate;

How can I demonstrate doctrine that those, when combined, form a composite unique key?

Asked by Nikoole

Solution #1

Answer the question:

use Doctrine\ORM\Mapping\UniqueConstraint;

/**
 * Common\Model\Entity\VideoSettings
 *
 * @Table(name="video_settings", 
 *    uniqueConstraints={
 *        @UniqueConstraint(name="video_unique", 
 *            columns={"video_dimension", "video_bitrate"})
 *    }
 * )
 * @Entity
 */

See @UniqueConstraint

Answered by Nikoole

Solution #2

I find that using merely ORM and then prefixing ORM in annotations is more verbose. Also, if you have multiple items to discuss, you can separate your annotation into several lines to make it more readable (index in the example below).

use Doctrine\ORM\Mapping as ORM;

/**
 * VideoSettings
 *
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\VideoSettingsRepository")
 * @ORM\Table(name="emails", uniqueConstraints={
 *      @ORM\UniqueConstraint(name="dimension_bitrate", columns={"video_dimension", "video_bitrate"})
 * }, indexes={
 *      @ORM\Index(name="name", columns={"name"})
 * })
 */
class VideoSettings

Answered by luchaninov

Solution #3

If you’d rather use PHP 8 attributes than Doctrine annotations, here’s how:

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\UniqueConstraint(
  name: 'video_unique_idx',
  columns: ['video_dimension', 'video_bitrate']
)]

Answered by Az.Youness

Solution #4

I realize this is an old question, but I came across it while seeking for a means to make composite PK and thought it needed to be updated.

If you only require a Composite Primary Key, things are a lot easier. (Which, of course, ensures exclusivity.) http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html offers several great examples from Doctrine documentation.

As a result, the original example might look like this:

/**
 * @var string $videoDimension
 *
 * @ORM\Id @ORM\Column(type="string")
 */
private $videoDimension;

/**
 * @var string $videoBitrate
 *
 * @ORM\Id @ORM\Column(type="string")
 */
private $videoBitrate;

A few points to consider:

Answered by Stas Parshin

Solution #5

XML version :

<unique-constraints>
    <unique-constraint columns="column1,column2" name="give_some_explicit_name" />
</unique-constraints>

More information may be found in the documentation at https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/xml-mapping.html#defining-indices-or-unique-constraints.

Answered by Balmipour

Post is based on https://stackoverflow.com/questions/12641698/doctrine-and-composite-unique-keys