Параметр cascade атрибута OneToMany
Параметр cascade атрибута OneToMany определяет,
какие операции, выполняемые над родительской сущностью,
будут автоматически применяться к связанным дочерним сущностям.
Значением параметра является массив строк, например ['persist', 'remove'].
Это позволяет сохранять или удалять связанные записи
без необходимости вызывать persist или remove
для каждой из них вручную.
Синтаксис
#[OneToMany(mappedBy: 'parent', targetEntity: Child::class, cascade: ['persist', 'remove'])]
Пример
Давайте создадим сущность Article,
у которой есть множество комментариев Comment.
Включим каскадное сохранение через параметр cascade:
<?php
namespace AppEntity;
use AppRepositoryArticleRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
#[ORMEntity(repositoryClass: ArticleRepository::class)]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $title = '';
#[ORMOneToMany(
mappedBy: 'article',
targetEntity: Comment::class,
cascade: ['persist', 'remove']
)]
private Collection $comments;
public function __construct()
{
$this->comments = new ArrayCollection();
}
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 getComments(): Collection
{
return $this->comments;
}
public function addComment(Comment $comment): self
{
if (!$this->comments->contains($comment)) {
$this->comments->add($comment);
$comment->setArticle($this);
}
return $this;
}
}
?>
Пример
Теперь создадим сущность Comment
с обратной связью ManyToOne на статью:
<?php
namespace AppEntity;
use AppRepositoryCommentRepository;
use DoctrineORMMapping as ORM;
#[ORMEntity(repositoryClass: CommentRepository::class)]
class Comment
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'text')]
private string $text = '';
#[ORMManyToOne(inversedBy: 'comments')]
private ?Article $article = null;
public function getId(): ?int
{
return $this->id;
}
public function getText(): string
{
return $this->text;
}
public function setText(string $text): self
{
$this->text = $text;
return $this;
}
public function getArticle(): ?Article
{
return $this->article;
}
public function setArticle(?Article $article): self
{
$this->article = $article;
return $this;
}
}
?>
Пример
Благодаря cascade: ['persist']
достаточно сохранить только статью,
а связанные комментарии сохранятся автоматически:
<?php
namespace AppController;
use AppEntityArticle;
use AppEntityComment;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/create', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$article = new Article();
$article->setTitle('article');
$comment1 = new Comment();
$comment1->setText('hello');
$comment2 = new Comment();
$comment2->setText('abcde');
$article->addComment($comment1);
$article->addComment($comment2);
$em->persist($article);
$em->flush();
return new Response('saved');
}
}
?>
Результат выполнения кода:
saved
Пример
При cascade: ['remove']
удаление статьи автоматически удалит все её комментарии:
<?php
namespace AppController;
use AppEntityArticle;
use AppRepositoryArticleRepository;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/delete/{id}', name: 'article_delete')]
public function delete(int $id, ArticleRepository $repo, EntityManagerInterface $em): Response
{
$article = $repo->find($id);
if ($article === null) {
return new Response('not found');
}
$em->remove($article);
$em->flush();
return new Response('deleted');
}
}
?>
Результат выполнения кода:
deleted
Смотрите также
-
атрибут
OneToMany,
который описывает связь "один ко многим" -
параметр
mappedBy,
который указывает владеющую сторону связи -
параметр
orphanRemoval,
который удаляет осиротевшие сущности -
параметр
cascadeатрибутаManyToOne,
который выполняет каскадные операции для обратной связи