Параметр unique атрибута JoinColumn
Параметр unique атрибута JoinColumn
указывает, что столбец внешнего ключа должен быть
уникальным. Если передать true, Doctrine
создаст уникальный индекс на этом столбце, и в таблице
не сможет появиться две записи с одинаковым значением
внешнего ключа. По умолчанию параметр равен false.
Чаще всего параметр unique: true используется
для организации связи «один-к-одному» на стороне
владельца связи, чтобы гарантировать, что на одну
запись основной сущности ссылается только одна запись
связанной сущности.
Синтаксис
#[JoinColumn(name: name, referencedColumnName: referencedColumnName, unique: true)]
Пример
Давайте создадим сущность User и связанную
с ней сущность Profile со связью
«один-к-одному». На стороне владельца связи поставим
unique: true, чтобы у одного пользователя был
только один профиль:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
#[ORMTable(name: 'users')]
class User
{
#[ORMId]
#[ORMColumn(type: 'integer')]
#[ORMGeneratedValue]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $name;
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
}
?>
Теперь сущность Profile, которая ссылается
на User через уникальный внешний ключ:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
#[ORMTable(name: 'profiles')]
class Profile
{
#[ORMId]
#[ORMColumn(type: 'integer')]
#[ORMGeneratedValue]
private ?int $id = null;
#[ORMColumn(type: 'text')]
private string $bio;
#[ORMOneToOne(targetEntity: User::class)]
#[ORMJoinColumn(name: 'user_id', referencedColumnName: 'id', unique: true)]
private ?User $user = null;
public function getId(): ?int
{
return $this->id;
}
public function getBio(): string
{
return $this->bio;
}
public function setBio(string $bio): self
{
$this->bio = $bio;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}
?>
Обновим схему базы данных командой:
php bin/console doctrine:schema:update --force
В результате на столбце user_id таблицы
profiles появится уникальный индекс. Теперь
попробуем сохранить два профиля для одного и того же
пользователя:
<?php
namespace AppController;
use AppEntityProfile;
use AppEntityUser;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
class ProfileController extends AbstractController
{
public function create(EntityManagerInterface $em): Response
{
$user = new User();
$user->setName('abcde');
$profile1 = new Profile();
$profile1->setBio('first');
$profile1->setUser($user);
$profile2 = new Profile();
$profile2->setBio('second');
$profile2->setUser($user);
$em->persist($user);
$em->persist($profile1);
$em->persist($profile2);
$em->flush();
return new Response('saved');
}
}
?>
Результат выполнения кода:
"An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'profiles.UNIQ_...'"
Как видно из результата, база данных не позволяет
создать второй профиль для того же пользователя из-за
уникального индекса, который был создан благодаря
параметру unique: true.
Смотрите также
-
атрибут
JoinColumn,
который задаёт столбец внешнего ключа -
связь
OneToOne,
которая организует связь «один-к-одному» -
параметр
name,
который задаёт имя столбца внешнего ключа -
параметр
nullable,
который разрешает или запрещает NULL в столбце