问题
I have a bit of problems with PreUpdate HasLifecycleCallbacks.
I have an entity, let say "A" with have a OneToOne relation with the entity "B". So I have:
/**
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks
*/
class A
{
/**
* @ORM\OneToOne(targetEntity="B", inversedBy="attrA", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="fieldB", referencedColumnName="id")
*/
private $attrB;
public function __construct()
{
$this->attrB = new B();
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updateSomthing(){
//$gestor = fopen("/pruebitas.txt", "r");
$this->attrB->setDate($this->getDate());
}
}
And class B is:
class B
{
/**
* @ORM\OneToOne(targetEntity="A", mappedBy="attrB")
*/
private $attrA;
}
When I create a new entity A, everything works fine, the problem is when I update the entity A, the PreUpdate function is fire, (because it creates the file in the commented line), but the entity B does not persist in the database, even if the field in B should be updated.
Any idea to cascade the persist on the PreUpdate??
Thanks!!
回答1:
Use preFlush
instead
From the Doctrine documentation of the preUpdate
event:
Changes to associations of the updated entity are never allowed in this event, since Doctrine cannot guarantee to correctly handle referential integrity at this point of the flush operation.
That makes sense, so you need to do your changes to associated entities before all the changesets are genereated by the Unit of Work. That's what the preFlush
event is for.
preFlush is called at EntityManager#flush() before anything else. EntityManager#flush() can be called safely inside its listeners.
Simply replace your @ORM\PreUpdate
annotation with @ORM\PreFlush
and it should work.
The preFlush
event is available since Doctrine 2.2.
Doctrine Documentation: "Events - preFlush"
Doctrine bug tracker: "preFlush event and lifecycle callback"
回答2:
You need to manually call ->recomputeSingleEntityChangeSet() on the unit of work if you make a change to an entity in a preUpdate listener.
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updateSomething($eventArgs)
{
$this->attrB->setDate($this->getDate());
$em = $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();
$meta = $em->getClassMetadata(get_class($entity));
$uow->recomputeSingleEntityChangeSet($meta, $entity);
}
来源:https://stackoverflow.com/questions/17546922/preupdate-cascade-entity-persist-symfony-2-3