Параметр cascade атрибута ManyToOne
Параметр cascade атрибута ManyToOne
указывает Doctrine автоматически выполнять
определённые операции над связанной сущностью
при сохранении или удалении сущности-владельца.
Значением параметра является массив строк,
например ['persist'] или ['remove'].
Чаще всего используется в связях, где дочерняя
сущность не должна существовать без родительской.
Синтаксис
#[ManyToOne(targetEntity: Entity::class, cascade: ['persist', 'remove'])]
Пример
Давайте создадим сущность Category
и сущность Article, где статья
принадлежит категории, а при сохранении статьи
категория сохраняется автоматически:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
class Category
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string')]
private string $title;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
}
?>
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string')]
private string $title;
#[ORMManyToOne(targetEntity: Category::class, cascade: ['persist'])]
#[ORMJoinColumn(nullable: false)]
private ?Category $category = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
}
?>
Теперь создадим статью вместе с новой категорией и сохраним только статью:
<?php
namespace AppController;
use AppEntityArticle;
use AppEntityCategory;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$category = new Category();
$category->setTitle('abcde');
$article = new Article();
$article->setTitle('hello');
$article->setCategory($category);
$em->persist($article);
$em->flush();
return new Response((string) $category->getId());
}
}
?>
Результат выполнения кода:
"1"
Благодаря cascade: ['persist'] категория
была сохранена автоматически вместе со статьёй,
хотя persist вызывался только для статьи.
Пример
Давайте добавим каскадное удаление, чтобы при удалении статьи удалялась и её категория:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
#[ORMEntity]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string')]
private string $title;
#[ORMManyToOne(targetEntity: Category::class, cascade: ['persist', 'remove'])]
#[ORMJoinColumn(nullable: false)]
private ?Category $category = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
}
?>
Теперь удалим статью:
<?php
namespace AppController;
use AppEntityArticle;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/delete/{id}', name: 'article_delete')]
public function delete(int $id, EntityManagerInterface $em): Response
{
$article = $em->getRepository(Article::class)->find($id);
$em->remove($article);
$em->flush();
return new Response('deleted');
}
}
?>
Результат выполнения кода:
"deleted"
Статья и связанная с ней категория были удалены
одним вызовом remove благодаря
cascade: ['remove'].
Смотрите также
-
атрибут
ManyToOne,
который задаёт связь многие-к-одному -
параметр
inversedBy,
который указывает обратное поле связи -
параметр
fetch,
который задаёт стратегию загрузки связи -
параметр
targetEntity,
который указывает целевую сущность связи