Php 条令多个关联实体:为什么removeXXX()不删除底层数据库记录?

Php 条令多个关联实体:为什么removeXXX()不删除底层数据库记录?,php,doctrine-orm,Php,Doctrine Orm,在这种情况下,我需要向多对多联接表中添加列,因此我尝试按照推荐的做法,将联接表表示为一个实体,该实体与其他两个实体都具有多对一关系 在本例中,我们有一个法庭口译员管理系统,其中有一个称为事件的实体,另一个称为口译员。解释器签名实体是一对多的,具有这两个属性,但它还需要两个元数据列:一个是createddatetime,另一个是创建它的Application\entity\User(为了简单起见,我省略了后者) 所以,这很好: $interpreter = $entityManager->g

在这种情况下,我需要向多对多联接表中添加列,因此我尝试按照推荐的做法,将联接表表示为一个实体,该实体与其他两个实体都具有多对一关系

在本例中,我们有一个法庭口译员管理系统,其中有一个称为事件的实体,另一个称为口译员。解释器签名实体是一对多的,具有这两个属性,但它还需要两个元数据列:一个是
created
datetime,另一个是创建它的
Application\entity\User
(为了简单起见,我省略了后者)

所以,这很好:

$interpreter = $entityManager->getRepository('Application\Entity\Interpreter')
    ->findOneBy(['lastname'=>'Mintz']);
$assignment = new Entity\InterpreterAssignment();
$assignment->setInterpreter($interpreter)->setEvent($event);
$event->addInterpretersAssigned($assignment);
$em->flush(); 
…我甚至不需要说
persist()
,因为
cascade={“persist”,“remove”}
事件#解释器分配

但是当我试着做相反的事情的时候,就是,, 使用条令为我编写的
removieinterpretersassigned()
方法:

$event = $entityManager->find('Application\Entity\Event',103510);
$assignment = $event->getInterpretersAssigned()[0];
$event->removeInterpretersAssigned($assignment);
$em->flush();
数据库未被触及;条令不会删除联接表中的行

我可以通过说
$entityManager->remove($assignment)
来解决这个问题。但是我忍不住认为
$event->removieinterpretersassigned($assignment)
应该可以工作

所以,我肯定错过了什么,但我看不到什么。cli工具说我的映射正常。以下是相关部分中的实体:

/* namespace declarations and use statements omitted */

class Event
{

    /* other fields and methods omitted */

    /**
     * @ORM\OneToMany(targetEntity="InterpreterAssignment",mappedBy="event",cascade={"persist","remove"})
     * @var InterpreterAssignment[]
     */
    protected $interpretersAssigned;

    /*  the following created by the Doctrine cli tool  */

    /**
     * Remove interpretersAssigned
     *
     * @param \Application\Entity\InterpreterAssignment $interpretersAssigned
     */
    public function removeInterpretersAssigned(\Application\Entity\InterpreterAssignment $interpretersAssigned)
    {
        $this->interpretersAssigned->removeElement($interpretersAssigned);
    }

    /**
     * Get interpretersAssigned
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getInterpretersAssigned()
    {
        return $this->interpretersAssigned;
    }
}

class Interpreter
{
    /**
     * @ORM\OneToMany(targetEntity="InterpreterAssignment",mappedBy="interpreter")
     * @var InterpreterAssignment[] 
     */
    protected $assignments;

     /**
     * Remove assignment
     *
     * @param \Application\Entity\InterpreterAssignment $assignment
     */
    public function removeAssignment(\Application\Entity\InterpreterAssignment $assignment)
    {
        $this->assignments->removeElement($assignment);
    }

    /**
     * Get assignments
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getAssignments()
    {
        return $this->assignments;
    }
}
这是
解释信号

/** 
 * @ORM\Entity 
 * @ORM\Table(name="interp_events", uniqueConstraints={@ORM\UniqueConstraint(name="unique_deft_event",columns={"interp_id","event_id"})}) 
 * @ORM\HasLifeCycleCallbacks
 */

class InterpreterAssignment
{

    /** 
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Interpreter",inversedBy="assignments")
     * @ORM\JoinColumn(name="interp_id", referencedColumnName="interp_id")
     * @var Interpreter
     */
    protected $interpreter;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Event",inversedBy="interpretersAssigned")
     * @ORM\JoinColumn(name="event_id", referencedColumnName="event_id")
     * @var Event
     */
    protected $event;


    /**
     * @ORM\Column(type="datetime",nullable=false)
     * @var \DateTime
     */
    protected $created;

    /**
     * @ORM\PrePersist
     */
    public function onPrePersist()
    {
        $this->created = new \DateTime();
    }

    /**
     * Set interpreter
     *
     * @param \Application\Entity\Interpreter $interpreter
     *
     * @return InterpreterAssignment
     */
    public function setInterpreter(\Application\Entity\Interpreter $interpreter)
    {
        $this->interpreter = $interpreter;

        return $this;
    }

    /**
     * Get interpreter
     *
     * @return \Application\Entity\Interpreter
     */
    public function getInterpreter()
    {
        return $this->interpreter;
    }

    /**
     * Set event
     *
     * @param \Application\Entity\Event $event
     *
     * @return InterpreterAssignment
     */
    public function setEvent(\Application\Entity\Event $event)
    {
        $this->event = $event;

        return $this;
    }

    /**
     * Get event
     *
     * @return \Application\Entity\Event
     */
    public function getEvent()
    {
        return $this->event;
    }

    /* other stuff ommitted */
}

非常感谢。

我想你需要做两件事:

  • (可选)在调用
    $event->removieinterpreserassigned($assignment)后,需要调用
    $assignment->setEvent(null)

  • 此外,您可能希望使用从多对多表中删除实体。因此,实体代码应更改为(请注意,映射代码中添加了
    ,orphanRemoving=true
    ):


  • 这很有效。非常感谢。唯一需要的额外修改是将
    解释器签名
    实体setEvent()的签名更改为接受NULL:
    公共函数setEvent(Event$Event=NULL)
    。将
    interpregrassignment
    $event
    属性设为空是违反直觉的。值得注意的是,我不必在数据库中使列为空。
     /**
      * @ORM\OneToMany(targetEntity="InterpreterAssignment",mappedBy="event",cascade={"persist","remove"}, orphanRemoval=true)
      * @var InterpreterAssignment[]
      */
     protected $interpretersAssigned;