Параметр orphanRemoval атрибута OneToMany
Параметр orphanRemoval атрибута OneToMany управляет
удалением дочерних сущностей, которые были удалены из коллекции
родительской сущности. Если параметр равен true, то при
исключении элемента из коллекции Doctrine удалит соответствующую
запись из базы данных. По умолчанию параметр равен false.
Синтаксис
#[OneToMany(mappedBy: 'parent', targetEntity: Child::class, orphanRemoval: true)]
Пример
Давайте создадим сущность Article с коллекцией комментариев
и включим автоматическое удаление сирот:
<?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')]
private string $title = '';
#[ORMOneToMany(
mappedBy: 'article',
targetEntity: Comment::class,
orphanRemoval: true
)]
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[] = $comment;
$comment->setArticle($this);
}
return $this;
}
public function removeComment(Comment $comment): self
{
if ($this->comments->removeElement($comment)) {
if ($comment->getArticle() === $this) {
$comment->setArticle(null);
}
}
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',
targetEntity: Article::class,
nullable: false
)]
#[ORMJoinColumn(nullable: false)]
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;
}
}
?>
Теперь удалим комментарий из коллекции статьи и сохраним изменения:
<?php
namespace AppController;
use AppEntityArticle;
use AppEntityComment;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/remove-comment', name: 'article_remove_comment')]
public function removeComment(EntityManagerInterface $em): Response
{
$article = $em->getRepository(Article::class)->find(1);
$comment = $em->getRepository(Comment::class)->find(1);
$article->removeComment($comment);
$em->flush();
return new Response('comment removed');
}
}
?>
Результат выполнения кода:
"comment removed"
При вызове removeComment и последующем flush
Doctrine удалит комментарий из базы данных, потому что
orphanRemoval установлен в true.
Пример
Если параметр orphanRemoval равен false,
то при удалении из коллекции запись в базе данных останется:
<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
#[ORMEntity]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMOneToMany(
mappedBy: 'article',
targetEntity: Comment::class,
orphanRemoval: false
)]
private Collection $comments;
public function __construct()
{
$this->comments = new ArrayCollection();
}
public function getComments(): Collection
{
return $this->comments;
}
public function removeComment(Comment $comment): self
{
$this->comments->removeElement($comment);
return $this;
}
}
?>
В этом случае комментарий останется в базе данных, но связь с artikkel будет разорвана.