It is not clear to me how to handle the operations from the OneToMany side.
Let us say object A is on the ManyToOne side, and object B on the OneToMany side.
I want when creating an object B, to assign many objects A to it - my solution in this was to fetch the A objects and assign to them the B object
I want when deleting an object B, to set to null all references from objects A - from researching I see that I probably have to add an ondelete="setNull"
functionality on the table
Is there a better way (or alternatives in general) to handle this situation?
use Doctrine\ORM\Mapping as ORM;
class AObject
{
// ...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\BObject", inversedBy="a", onDelete="SET NULL")
*/
private $b;
}
class BObject
{
// ...
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\AObject", mappedBy="b", cascade={"persist"})
*/
private $a;
public function __construct()
{
$this->a = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return \Doctrine\Common\Collections\ArrayCollection
*/
public getA()
{
return $this->a;
}
/**
* @param \Doctrine\Common\Collections\ArrayCollection $a
*/
public setA($a)
{
$this->a = $a;
}
/**
* @param AObject $a
* @return BObject
*/
public addA($a)
{
$this->a[] = $a;
$a->setB($this); // assign B object to A
return $this; // For method chaining
}
/**
* @param AObject $a
*/
public removeA($a)
{
$this->a->removeElement($a);
}
}
For 1) you'll still have to fetch your objects, your code can't magically know which A objects assign to your new B object.
With the class B defined above, you can write
$b = new BObject();
$b
->addA($a1)
->addA($a2)
->addA(new AObject());
$entityManager->persist($b);
$entityManager->flush();
and A objects will have the reference to B.
For 2) it's yet the better solution, handle it to the database level.
For your purposes you can use doctrine lifecycle events .
For sample, first you need to define event listener:
# /src/FooBundle/Resources/config/services.yml
services:
# Event subscribers
foo.bar.subscriber:
class: FooBundle\EventListener\BarSubscriber
tags:
- { name: doctrine.event_subscriber }
Then, create one:
// FooBundle\EventListener\BarSubscriber.php
namespace FooBundle\EventListener;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
class BarSubscriber implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(
'preRemove',
'postPersist',
);
}
// This method will be executed on each entity, before it has been deleted
// You can do here what u want in your second paragraph
public function preRemove(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
// Do not forget to check your entity type
if (!$entity instanceof SomeInterface) {
return;
}
// Some code that handle some actions on related entites
}
// This code will be executed after each entity creation
// Here you can add more relations for your main entity
public function postPersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof TimestampableInterface) {
return;
}
// Some actions on relations, after the establishment of the main object
}
}
Also, as an alternative, you can use Doctrine cascade operations , for removing all child entites
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.