Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 条令级联={remove}通过onDelete=";删除实体时不工作;“级联”;_Php_Doctrine Orm - Fatal编程技术网

Php 条令级联={remove}通过onDelete=";删除实体时不工作;“级联”;

Php 条令级联={remove}通过onDelete=";删除实体时不工作;“级联”;,php,doctrine-orm,Php,Doctrine Orm,我在使用条令2的实体之间的级联关系中遇到了一个问题 我有一个媒体实体,与父事件相关: class Media { /** * @ORM\OneToOne(targetEntity="Event", mappedBy="media") */ private $event; public function getEvent() { return $this->event; } public functio

我在使用条令2的实体之间的级联关系中遇到了一个问题

我有一个
媒体
实体,与父事件相关:

class Media
{

    /**
     * @ORM\OneToOne(targetEntity="Event", mappedBy="media")
     */
    private $event;

    public function getEvent()
    {
        return $this->event;
    }

    public function setEvent(Event $event)
    {
        $this->event = $event;
    }

}
每个
事件
都与媒体(双向)相关,也与
导入
实体相关

class Event
{

    /**
     * @ORM\JoinColumn(name="media", referencedColumnName="id", onDelete="SET NULL")
     * @ORM\OneToOne(targetEntity="Media", inversedBy="event", cascade={"persist", "remove"}, orphanRemoval=true)
     */
    private $media;

    public function getMedia()
    {
        return $this->media;
    }

    public function setMedia(Media $media = null)
    {
        $this->media = $media;
    }


    /**
     * @ORM\JoinColumn(name="import", referencedColumnName="id", nullable=true, onDelete="CASCADE")
     * @ORM\ManyToOne(targetEntity="Import")
     */
    private $import;

    public function getImport()
    {
        return $this->import;
    }

    public function setImport(Import $import = null)
    {
        $this->import = $import;
    }

}

预期的行为如下所示:

  • 事件
    实体在其父级
    导入
    被删除时自动删除(与
    onDelete=“CASCADE”
    的多通关系)
  • 事件
    实体还包含对
    媒体
    实体的引用(OneToOne关系),删除事件时必须删除该引用
两者都运作良好:

  • 如果删除导入,将删除所有相关事件
  • 如果我删除某个事件,则相关媒体将被删除
但是,如果我删除导入,尽管事件已被删除,但与已删除事件相关的媒体不会被删除


对可能发生的事情有什么想法吗?谢谢

您描述的问题是预期的行为。
onDelete=“CASCADE”
选项强制数据库内部执行的行为,而
CASCADE={“remove”}
选项通过条令处理并应用于内存中执行的对象,如下所述:

级联操作在内存中执行。这意味着在即将执行级联操作时,集合和相关实体将被提取到内存中(即使它们被标记为惰性)。这种方法允许为每个操作执行实体生命周期事件

这两种方法都是有效的,但正如所讨论的,它们意味着不同的事情


设置中实际发生的情况是,您希望在您的场景中混合使用
onDelete=“CASCADE”
CASCADE={“remove”}
,但由于它们的性质,它们无法一起运行

实际上,由于在
Import
中没有与
cascade={“remove”}
相反的一面,因此在删除
Import
时:

  • 在数据库中对与
    Import
    对应的表执行
    DELETE
    操作
  • 由于表中的外键用于
    事件
    ,与
    导入
    相关的事件将直接在数据库中删除
从此处,不执行任何其他操作,因为用于
媒体的表
没有任何外键引用
事件
表(因为它位于关联的反面)


有两件事可以让这一切顺利进行:

反转媒体/事件关联,并在
媒体
表中添加
onDelete=“CASCADE”
在Media.php中

在Event.php中

使用这种方法,删除数据库中的
导入
条目必然会删除相关的
事件
条目,并且通过相同的机制,相关的
媒体
将被删除(所有这一切都是由数据库直接完成的,我们刚刚在
导入
表上发布了一个
删除
操作)

Import
中添加一个反向边,并使用
cascade={“remove”}
如果使用
cascade={“remove”}
Import
中添加反向
OneToMany
,则使用实体管理器执行的删除操作将级联到相关的
事件
实体,该实体也将级联删除操作到任何相关的
介质

如果您希望为这些实体执行生命周期事件,这将非常有用


这并不意味着您必须在两种方法之间进行选择。文件规定如下:

但是,您应该知道,使用策略1(CASCADE=REMOVE)完全绕过任何外键onDelete=CASCADE选项,因为条令将显式地获取和删除所有相关实体


也就是说,如果您希望数据库保持正确的状态,那么除了
CASCADE={“remove”}
之外还有
onDelete=CASCADE
。例如,如果您直接执行
DELETE
查询(不使用实体管理器),则在没有
onDelete=CASCADE
的情况下,相关条目不会被删除,您的RDBMS很可能会抱怨无效的外键约束。

这在解释时似乎非常明显。。。我太专注于ORM设置,以至于忽略了这种行为。谢谢你的澄清!
/**
 * @ORM\OneToOne(targetEntity="Event", inversedBy="media")
 * @ORM\JoinColumn(onDelete="CASCADE")
 */
private $event;
/**
 * @ORM\OneToOne(targetEntity="Media", mappedBy="event")
 */
private $media;