Doctrine 返回通过 onDelete 删除的实体:'cascade'

问题描述 投票:0回答:1

我正在使用具有 onDelete: 'cascade' 的关系来解决一个奇怪的问题。 简而言之,我删除了父对象,级联在数据库中工作正常,也删除了子对象。 然后,如果我再次通过entityManager->find()读取对象,则无法找到父实体,而ORM会找到子实体,即使数据库中没有这样的对象。

我真的很感激任何想法,因为我已经尝试了很多不同的事情,但没有运气......但我想我没有发现一些明显的错误。

这是我的代码:

<?php
require_once "bootstrap.php";

// create objects
$s1 = new Shelf();
$s1->setCategory("Science fiction");
$entityManager->persist($s1);

$b1 = new Book();
$b1->setAuthor("Isaac Asimov");
$b1->setTitle("End of Eternity");
$b1->setShelf($s1);
$entityManager->persist($b1);
$entityManager->flush();

$shelfId = $s1->getId();
$bookId = $b1->getId();

// delete objects
$entityManager->remove($s1);
$entityManager->flush();
// --> this deletes on the DB both the shelf and the book

// read the objects again
$shelfAfterDel = $entityManager->find(Shelf::class, $shelfId);
$bookAfterDel = $entityManager->find(Book::class, $bookId);

echo "shelf: " . ($shelfAfterDel!=null? $shelfAfterDel->getCategory() : "null") . "\n"; 
// --> this prints 'null' (OK)
echo "book: " . ($bookAfterDel!=null? $bookAfterDel->getTitle() : "null") . "\n"; 
// --> this prints 'End of Eternity' (NOT OK)

货架.php

<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

#[ORM\Entity]
#[ORM\Table(name: 'shelf')]
class Shelf
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column]
    private string $category;

    #[ORM\OneToMany(targetEntity: Book::class, mappedBy: 'shelf')]
    private Collection $books;

    public function __construct()
    {
        $this->books = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getCategory(): string
    {
        return $this->category;
    }

    public function setCategory(string $category): void
    {
        $this->category = $category;
    }

    public function addBook(Book $book): void
    {
        $this->books[] = $book;
    }
}

Book.php

<?php
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'book')]
class Book
{
    #[ORM\Id]
    #[ORM\Column]
    #[ORM\GeneratedValue]
    private ?int $id = null;

    #[ORM\Column]
    private string $author;

    #[ORM\Column]
    private string $title;

    #[ORM\ManyToOne(targetEntity: Shelf::class, inversedBy: 'books')]
    #[ORM\JoinColumn(onDelete: 'CASCADE', nullable: false)]
    private Shelf $shelf;

    public function setShelf(Shelf $shelf): void
    {
        $this->shelf = $shelf;
    }

    public function getShelf(): Shelf
    {
        return $this->shelf;
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getAuthor(): string
    {
        return $this->author;
    }

    public function setAuthor(string $author): void
    {
        $this->author = $author;
    }

    public function setTitle($title): void
    {
        $this->title = $title;
    }

    public function getTitle():string
    {
        return $this->title;
    }
}

bootstrap.php

require_once "vendor/autoload.php";

$config = ORMSetup::createAttributeMetadataConfiguration(
    paths: [__DIR__ . '/src'],
    isDevMode: true,
);
$connection = DriverManager::getConnection([
    'driver'   => 'pdo_mysql',
    'host'     => '127.0.0.1',
    'port'     => '3306',
    'user'     => 'root',
    'password' => 'XXXXXX',
    'dbname'   => 'phpunit',
], $config);

$entityManager = new EntityManager($connection, $config);

composer.json

{
    "require": {
        "php": ">=8.0.0",
        "monolog/monolog": "^3.8",
        "doctrine/orm": "^3",
        "doctrine/dbal": "^4",
        "symfony/cache": "^7"
    },
    "autoload": {
        "psr-4": {
          "": "src/"
        }
      },
      "archive": {
        "exclude": [
          "vendor",
          ".DS_Store",
          "*.log"
        ]
      }
}
php doctrine-orm doctrine
1个回答
0
投票

通常 Doctrine 不知道刷新后数据库级别发生了什么,因为实体是在内存中管理的,调用

$entityManager->clear();
通过清除身份映射来解决此问题,强制 Doctrine 从数据库中获取新数据以进行后续操作。 https://stackoverflow.com/a/59970767/16742310

© www.soinside.com 2019 - 2024. All rights reserved.