原则2 / 将元素从一个集合移动到另一个集合



我有3个实体:InvoiceServiceLine

  • Invoice包含Service的集合
  • Service包含Line的集合

我想将一个LineService集合移动到另一个Service集合,但在刷新时,我尝试移动的Line元素从数据库中删除......

单元测试在没有持久/刷新的情况下是可以

使用示例 :

if ($transferService)
{
    $line->transferToService($service1, $service2);
}
else
{
    $line->setService($service2);
}

发票:

class Invoice
{
    /**
     * @ORMOneToMany(targetEntity="Service", mappedBy="invoice", cascade={"persist", "merge", "remove"}, orphanRemoval=true)
     */
    protected $services;
    // ...
    public function __construct()
    {
        $this->services = new ArrayCollection();
    }
    #################################################
    # SERVICES Array Collection handling            #
    #################################################
    public function getServices()
    {
        return $this->services;
    }
    public function setServices($services)
    {
        $this->services = new ArrayCollection();
        return $this->addServices($services);
    }
    public function addService(Service $service)
    {
        if (!$this->services->contains($service))
        {
            $this->services->add($service);
            $service->setInvoice($this);
        }
        return $this;
    }
    public function addServices($services)
    {
        foreach ($services as $service)
        {
            $this->addService($service);
        }
        return $this;
    }
    public function removeService(Service $service)
    {
        if ($this->services->contains($service))
        {
            $this->services->removeElement($service);
        }
        return $this;
    }
    public function removeServices($services)
    {
        foreach ($services as $service)
        {
            $this->removeService($service);
        }
        return $this;
    }        
    // ...
}

服务:

class Service
{
    /**
     * @ORMOneToMany(targetEntity="Line", mappedBy="service", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
     */
    protected $lines;
    /**
     * @ORMManyToOne(targetEntity="Invoice", inversedBy="services", cascade={"persist", "merge"})
     * @ORMJoinColumn(name="invoice_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $invoice;
    // ...
    public function __construct()
    {
        $this->lines = new ArrayCollection();
    }
    public function getInvoice()
    {
        return $this->invoice;
    }
    public function setInvoice(Invoice $invoice)
    {
        $this->invoice = $invoice;
        $invoice->addService($this);
        return $this;
    }
    #################################################
    # LINES Array Collection handling               #
    #################################################
    public function setLines($lines)
    {
        $this->lines = new ArrayCollection();
        return $this->addLines($lines);
    }
    public function getLines()
    {
        return $this->lines;
    }
    public function addLine(Line $line)
    {
        if (!$this->lines->contains($line))
        {
            $this->lines->add($line);
            $line->setService($this);
        }
        return $this;
    }
    public function addLines($lines)
    {
        foreach ($lines as $line)
        {
            $this->addLine($line);
        }
        return $this;
    }
    public function removeLine(Line $line)
    {
        if ($this->lines->contains($line))
        {
            $this->lines->removeElement($line);
        }
        return $this;
    }
    public function removeLines($lines)
    {
        foreach ($lines as $line)
        {
            $this->removeLine($line);
        }
        return $this;
    }
    // ...
}

线:

class Line
{
    /**
     * @ORMManyToOne(targetEntity="Service", inversedBy="lines", cascade={"persist", "merge"})
     * @ORMJoinColumn(name="service_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $service;
    public function setService(Service $service)
    {
        $this->service = $service;
        $service->addLine($this);
        return $this;
    }
    public function transferToService(Service $serviceFrom, Service $serviceTo)
    {
        $this->setService($serviceTo);
        $serviceFrom->removeLine($this);
        return $this;
    }
    public function getService()
    {
        return $this->service;
    }
    // ...
}
这是

由于orphanRemoval={true} .这意味着集合对象仅从"原始"所有者(例如:Line私有。看这里

您的代码似乎运行良好,除非 - 也许您没有注意到 - 原始元素消失了,但它们也使用不同的 id 再次创建。请检查这种情况,因为我不止一次经历过同样的情况。

因此,如果要保留相同的对象,则应删除orphanRemoval并手动处理自己的集合生命周期(包括删除;我敢打赌,您正在使用它在表单集合和嵌入式表单中尽可能少地编写代码)

相关内容

最新更新