【问题标题】:Doctrine update entity with arraycollection dont remove items带有 arraycollection 的教义更新实体不删除项目
【发布时间】:2018-11-22 18:40:24
【问题描述】:

我有这些课程:

AbstractBillingInvoice

/**
 * @ORM\Table(name="billing_invoice")
 * @ORM\Entity(repositoryClass="BillingBundle\Repository\AbstractBillingInvoiceRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="billingInvoiceType", type="string")
 * @ORM\DiscriminatorMap({"ProFormaInvoice" = "\BillingBundle\Entity\BillingInvoices\ProFormaInvoice", "Invoice" = "\BillingBundle\Entity\BillingInvoices\Invoice"})
 * @GRID\Column(id="billingInvoiceType", filterable=false, type="abstract_billing_invoice")
 * @GRID\Column(id="downloadInvoice", filterable=false, type="download_invoice", safe=false)
 * @Gedmo\SoftDeleteable()
 */
abstract class AbstractBillingInvoice
{
.....
    /**
     * @ORM\OneToMany(targetEntity="BillingBundle\Entity\BillingInvoiceItem", mappedBy="billingInvoice", cascade={"persist","remove"}, orphanRemoval=true)
     */
    private $billingInvoiceItems;
......
    public function __construct()
    {
        $this->billingInvoiceItems = new ArrayCollection();
    }

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

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getBillingInvoiceItems()
    {
        return $this->billingInvoiceItems;
    }

    public function setBillingInvoiceItems($billingInvoiceItems)
    {
        $this->billingInvoiceItems = $billingInvoiceItems;

        return $this;
    }

    public function addBillingInvoiceItems(BillingInvoiceItem $billingInvoiceItems)
    {
        $billingInvoiceItems->setBillingInvoice($this);
        $this->billingInvoiceItems->add($billingInvoiceItems);

        return $this;
    }

    public function removeBillingInvoiceItems(BillingInvoiceItem $billingInvoiceItems)
    {
        if ($this->billingInvoiceItems->contains($billingInvoiceItems)) {
            $this->billingInvoiceItems->remove($billingInvoiceItems);
        }

        return $this;
    }

和 BillingInvoiceItem

class BillingInvoiceItem
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="BillingBundle\Entity\AbstractBillingInvoice", inversedBy="billingInvoiceItems")
     * @ORM\JoinColumn(nullable=false, referencedColumnName="id")
     * @Assert\NotBlank()
     */
    private $billingInvoice;
.....
    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function setBillingInvoice($billingInvoice)
    {
        $this->billingInvoice = $billingInvoice;

        return $this;
    }

    public function getBillingInvoice()
    {
        return $this->billingInvoice;
    }

一切正常,除了一件事 - 我无法从收藏中删除项目。添加项没有问题,但是如果缺少某些项,则有两种情况-如果删除了ArrayCollection的最后一个元素,则数据库中没有任何反应。如果删除了其他元素,则复制最后一个元素而不是它。

如果我在 onFlush 方法中的 EntityListenere 中转储实体 AbstractBillingInvoice,我会看到数据正确。如果我删除元素,元素确实丢失了,但是在刷新之后这个元素又回到了数据库中。

我做错了什么?

非常感谢 D

【问题讨论】:

    标签: symfony doctrine entity arraycollection


    【解决方案1】:

    通常我们通过ArrayCollection 管理来自use Doctrine\Common\Collections\ArrayCollection; 包的许多关系。

    你可以像这样更新你的代码:

    public function __construct() {
        $this->billingInvoice = new ArrayCollection();
        // [...]
    }
    public function getBillingInvoice(){
        return $this->billingInvoice->toArray();
    }
    
    public function addBillingInvoice(BillingInvoice $billingInvoice){
        if(!$this->billingInvoice->contains($billingInvoice)){
            $this->billingInvoice->add($billingInvoice);
        }
    }
    
    public function removeBillingInvoice(BillingInvoice $billingInvoice){
        if($this->billingInvoice->contains($billingInvoice)){
            $this->billingInvoice->removeElement($billingInvoice);
        }
    }
    

    然后当你想删除一个关系时,只需调用:

    $myEntity->removeBillingInvoice($myBillingInvoice);
    $em->persist($myEntity);
    $em->flush();
    

    但我不确定这是否能解决您最初的问题,您是否尝试检查 tou billingInvoice 实体是否也删除了反向映射?

    【讨论】:

    • 您好,从ArrayCollection中移除元素没有问题。刷新前的实体设置正确。但刷新后,所有发票项目仍在数据库中。添加项目可以,也可以更改项目,但不能删除项目。如果我删除最后一个元素,什么都不会发生,如果我从中间删除元素,最后一个元素将设置到它的位置(复制到它的 id)。
    • 我已经解决了这个问题: $billingInvoiceItemFromDb = $this->billingInvoiceItemRepository->findBy( [ 'billingInvoice' => $entity, ] ); foreach ($billingInvoiceItemFromDb as $item) { if (!$entity->getBillingInvoiceItems()->contains($item)) { $this->billingInvoiceItemRepository->delete($item); } }
    • 是的,我的意思是删除反向映射。很高兴您解决了您的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2012-11-26
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多