Параметр nullable атрибута JoinColumn
Параметр nullable атрибута JoinColumn
управляет тем, может ли колонка внешнего ключа
в базе данных содержать значение NULL.
По умолчанию параметр равен true, то есть
связь необязательна. Если установить false,
то при сохранении сущности без связанного объекта
Doctrine выбросит ошибку целостности.
Параметр принимает булево значение: true
разрешает NULL во внешнем ключе,
а false запрещает его. Это влияет
на генерацию SQL-схемы и на работу уровня
валидации перед вставкой в базу данных.
Синтаксис
#[JoinColumn(nullable: true)]
Пример
Давайте создадим сущность Article со связью
многие-к-одному на сущность User и разрешим
значение NULL во внешнем ключе:
<?php
namespace App\Entity;
use App\Repository\ArticleRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ArticleRepository::class)]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(nullable: true)]
private ?User $user = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
}
?>
Теперь создадим сущность User с обратной связью
один-ко-многим:
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\OneToMany(mappedBy: 'user', targetEntity: Article::class)]
private Collection $articles;
public function __construct()
{
$this->articles = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
public function getArticles(): Collection
{
return $this->articles;
}
}
?>
Сгенерируем схему базы данных:
php bin/console doctrine:schema:update --force
Doctrine создаст колонку user_id без ограничения
NOT NULL. Теперь можно сохранить статью
без автора:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/article', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$article = new Article();
$article->setTitle('article');
$em->persist($article);
$em->flush();
return new Response('saved id: ' . $article->getId());
}
}
?>
Результат выполнения кода для адреса /article:
"saved id: 1"
Пример
Теперь запретим значение NULL во внешнем ключе,
установив nullable: false:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): static
{
$this->user = $user;
return $this;
}
}
?>
Теперь колонка user_id будет создана
с ограничением NOT NULL. Попробуем
сохранить статью без автора:
<?php
namespace App\Controller;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/article', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$article = new Article();
$article->setTitle('article');
$em->persist($article);
$em->flush();
return new Response('saved');
}
}
?>
Результат выполнения кода выбросит исключение:
"NOT NULL constraint failed: article.user_id"
Смотрите также
-
атрибут
JoinColumn,
который настраивает колонку внешнего ключа -
параметр
name,
который задаёт имя колонки внешнего ключа -
параметр
referencedColumnName,
который указывает связанную колонку -
параметр
onDelete,
который задаёт поведение при удалении связанной записи