PreUpdate级联实体持久化symfony 2.3

时间:2013-07-09 11:21:02

标签: symfony entity updates cascade persist

我对PreUpdate HasLifecycleCallbacks有一些问题。

我有一个实体,假设“A”与实体“B”具有OneToOne关系。 所以我有:

/**
 * @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());
   }
}

B级是:

class B
{
    /**
     * @ORM\OneToOne(targetEntity="A", mappedBy="attrB")
     */
    private $attrA;
}

当我创建一个新的实体A时,一切正常,问题是当我更新实体A时,PreUpdate函数是fire,(因为它在注释行中创建文件),但实体B不会持久化在数据库中,即使B中的字段应该更新。

有任何想法在PreUpdate上级联持久性吗?

谢谢!

2 个答案:

答案 0 :(得分:9)

使用preFlush代替

来自preUpdate事件的Doctrine文档:

  

永远不允许对更新后的实体的关联进行更改   这个事件,因为Doctrine无法保证正确处理   刷新操作此时的参照完整性。

这是有道理的,因此您需要在所有变更集由工作单位处理之前对关联实体进行更改。这就是preFlush事件的用途。

  

preFlush在EntityManager#flush()之前调用。   可以在其侦听器内安全地调用EntityManager#flush()。

只需将@ORM\PreUpdate注释替换为@ORM\PreFlush,它就可以正常使用。

自{Doctrine 2.2}以来preFlush事件可用。

Doctrine Documentation: "Events - preFlush"

Doctrine bug tracker: "preFlush event and lifecycle callback

答案 1 :(得分:-1)

如果您对preUpdate侦听器中的实体进行了更改,则需要在工作单元上手动调用 - > recomputeSingleEntityChangeSet()。

/**
 * @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);
}