Discussion:
[doctrine-user] Doctrine doesnt remove ArrayCollection elements
Darius Radius
2018-06-13 09:09:13 UTC
Permalink
Hello, I have my question here
https://stackoverflow.com/questions/50832866/doctrine-update-entity-with-arraycollection-dont-remove-items
and my summary is:

I have classess:

/**
* @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\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @GRID\Column(visible=false, filterable=false)
*/
private $id;/**
* @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;
}





and class:

/**
* @ORM\Table(name="billing_invoice_item")
*
@ORM\Entity(repositoryClass="BillingBundle\Repository\BillingInvoiceItemRepository")
* @Gedmo\SoftDeleteable()
*/
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;
/**
*
@ORM\ManyToOne(targetEntity="BillingBundle\Entity\AbstractBillingPriceList")
* @ORM\JoinColumn(nullable=true, referencedColumnName="id")
*/
private $itemCode;




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;
}




public function getItemCode()
{
return $this->itemCode;
}


public function setItemCode($itemCode)
{
$this->itemCode = $itemCode;
}





I have no problem with saving new entity (with or without invoice items),
there is no problem with update billing invoice entity with newly added
invoice items, but I am not able to update billing invoice arraycollection
when I remove any billing invoice item (but all changes in billing invoice
entity are saved correctly).

What I missed?

Thank you
Darius
--
You received this message because you are subscribed to the Google Groups "doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to doctrine-user+***@googlegroups.com.
To post to this group, send email to doctrine-***@googlegroups.com.
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.
Marco Pivetta
2018-06-13 09:50:30 UTC
Permalink
That's only the entity definition: what is your code doing? Can you maybe
write a test case like the ones at
https://github.com/doctrine/doctrine2/tree/master/tests/Doctrine/Tests/ORM/Functional/Ticket
?

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/
Hello, I have my question here https://stackoverflow.com/
questions/50832866/doctrine-update-entity-with-
/**
AbstractBillingInvoiceRepository")
BillingInvoices\ProFormaInvoice", "Invoice" = "\BillingBundle\Entity\
BillingInvoices\Invoice"})
type="abstract_billing_invoice")
type="download_invoice", safe=false)
*/
abstract class AbstractBillingInvoice
{
/**
*/
private $id;/**
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;
}
/**
BillingInvoiceItemRepository")
*/
class BillingInvoiceItem
{
/**
*/
private $id;
/**
inversedBy="billingInvoiceItems")
*/
private $billingInvoice;
/**
AbstractBillingPriceList")
*/
private $itemCode;
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;
}
public function getItemCode()
{
return $this->itemCode;
}
public function setItemCode($itemCode)
{
$this->itemCode = $itemCode;
}
I have no problem with saving new entity (with or without invoice items),
there is no problem with update billing invoice entity with newly added
invoice items, but I am not able to update billing invoice arraycollection
when I remove any billing invoice item (but all changes in billing invoice
entity are saved correctly).
What I missed?
Thank you
Darius
--
You received this message because you are subscribed to the Google Groups
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to doctrine-user+***@googlegroups.com.
To post to this group, send email to doctrine-***@googlegroups.com.
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.
Darius Radius
2018-06-13 10:05:51 UTC
Permalink
Hello,

I have form where I am simply using jquery collection for adding, changing
and removing BillingInvoiceItems. Below is updateFunction from Symfony
Controller, which manage update action and with (stupid but working) hotfix
of this problem. In this controller action is AbstractBillingInvoice
correctly set because there is billingInvoiceItems without removed element.
NOTE: function save is part making persist and flush.

public function updateAction(AbstractBillingInvoice $entity, Request $request): Response
{
if ($entity instanceof ProFormaInvoice && !empty($entity->getBillingPayment())) {
$this->addFlash(FlashModel::WARNING, 'This invoice cannot be updated.');

return $this->redirectResponse($request, $this->generateUrl('billing_invoice_list'));
}

$billingInvoiceIdentifierLabel = $entity->getBillingInvoiceIdentifier()->getLabel();

$formType = strtr(get_class($entity).'Type', ['\Entity\\' => '\Form\\']);

$form = $this->createForm(
$formType,
$entity,
array_merge(
[],
$this->isApiCall($request) ? ['csrf_protection' => false] : []
)
);
$form->handleRequest($request);

if ($form->isValid()) {
$billingInvoiceItemFromDb = $this->billingInvoiceItemRepository->findBy(
[
'billingInvoice' => $entity,
]
);

/** @var BillingInvoiceItem $billingInvoiceItem */
foreach ($entity->getBillingInvoiceItems()->getIterator() as $billingInvoiceItem) {
$billingInvoiceItem->setBillingInvoice($entity);
}

foreach ($billingInvoiceItemFromDb as $item) {
if (!$entity->getBillingInvoiceItems()->contains($item)) {
$this->billingInvoiceItemRepository->delete($item);
}
}

$this->abstractBillingInvoiceRepository->save($entity);
$this->addFlash(FlashModel::SUCCESS, 'Updated invoice was sended to customer.');

$this->billingInvoiceMailSender->sendInvoice($entity->getId(), true);

return $this->afterSaveAction($request, 'billing_invoice', $entity->getId(), 'id');
}
if ($this->isApiCall($request) && $form->isSubmitted() && !$form->isValid()) {
return $this->jsonResponse($form->getErrors(), 200);
}

return $this->output(
'BillingBundle:BillingInvoiceController/Invoices/'.$billingInvoiceIdentifierLabel.':update.html.twig',
[
'form' => $form->createView(),
'billingInvoice' => $entity,
],
null,
$request
);
}
Post by Marco Pivetta
That's only the entity definition: what is your code doing? Can you maybe
write a test case like the ones at
https://github.com/doctrine/doctrine2/tree/master/tests/Doctrine/Tests/ORM/Functional/Ticket
?
Marco Pivetta
http://twitter.com/Ocramius
http://ocramius.github.com/
Post by Darius Radius
Hello, I have my question here
https://stackoverflow.com/questions/50832866/doctrine-update-entity-with-arraycollection-dont-remove-items
/**
*
@ORM\Entity(repositoryClass="BillingBundle\Repository\AbstractBillingInvoiceRepository")
"\BillingBundle\Entity\BillingInvoices\ProFormaInvoice", "Invoice" =
"\BillingBundle\Entity\BillingInvoices\Invoice"})
type="abstract_billing_invoice")
type="download_invoice", safe=false)
*/
abstract class AbstractBillingInvoice
{
/**
*/
private $id;/**
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;
}
/**
*
@ORM\Entity(repositoryClass="BillingBundle\Repository\BillingInvoiceItemRepository")
*/
class BillingInvoiceItem
{
/**
*/
private $id;
/**
*
@ORM\ManyToOne(targetEntity="BillingBundle\Entity\AbstractBillingInvoice",
inversedBy="billingInvoiceItems")
*/
private $billingInvoice;
/**
*
@ORM\ManyToOne(targetEntity="BillingBundle\Entity\AbstractBillingPriceList")
*/
private $itemCode;
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;
}
public function getItemCode()
{
return $this->itemCode;
}
public function setItemCode($itemCode)
{
$this->itemCode = $itemCode;
}
I have no problem with saving new entity (with or without invoice items),
there is no problem with update billing invoice entity with newly added
invoice items, but I am not able to update billing invoice arraycollection
when I remove any billing invoice item (but all changes in billing invoice
entity are saved correctly).
What I missed?
Thank you
Darius
--
You received this message because you are subscribed to the Google Groups
"doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "doctrine-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to doctrine-user+***@googlegroups.com.
To post to this group, send email to doctrine-***@googlegroups.com.
Visit this group at https://groups.google.com/group/doctrine-user.
For more options, visit https://groups.google.com/d/optout.
Loading...