简体   繁体   English

Symfony 3 / Doctrine - 获取实体更改集中关联的更改

[英]Symfony 3 / Doctrine - Get changes to associations in entity change set

So I already know that I can get changes to a specific entity in the preUpdate lifecycle event: 所以我已经知道我可以在preUpdate生命周期事件中对特定实体进行更改:

/**
 * Captures pre-update events.
 * @param PreUpdateEventArgs $args
 */
 public function preUpdate(PreUpdateEventArgs $args)
 {
     $entity = $args->getEntity();


     if ($entity instanceof ParentEntity) {
            $changes = $args->getEntityChangeSet();
     }
 }

However, is there a way to also get changes for any associated Entities? 但是,有没有办法同时获得任何相关实体的更改? For example, say ParentEntity has a relationship setup like so: 例如,说ParentEntity的关系设置如下:

/**
 * @ORM\OneToMany(targetEntity="ChildEntity", mappedBy="parentEntity", cascade={"persist", "remove"})
 */
 private $childEntities;

And ChildEntity also has: ChildEntity也有:

/**
 * @ORM\OneToMany(targetEntity="GrandChildEntity", mappedBy="childEntity", cascade={"persist", "remove"})
 */
 private $grandChildEntities;

Is there a way to get all relevant changes during the preUpdate of ParentEntity ? 有没有办法在preUpdateParentEntity期间获得所有相关更改?

All of the associated entities from a OneToMany or ManyToMany relationships appear as a Doctrine\\ORM\\PersistentCollection . OneToMany或ManyToMany关系中的所有关联实体都显示为Doctrine \\ ORM \\ PersistentCollection

Take a look at the PersistentCollection's API, it have some interesting public methods even if they are marked as INTERNAL: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/PersistentCollection.php#L308 看一下PersistentCollection的API,它有一些有趣的公共方法,即使它们被标记为INTERNAL: https//github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/PersistentCollection.php#L308

For example you can check if your collection is dirty which means that its state needs to be synchronized with the database. 例如,您可以检查您的集合是否为脏,这意味着其状态需要与数据库同步。 Then you can retrieve the entities that have been removed from the collection or inserted into it. 然后,您可以检索已从集合中删除或插入其中的实体。

if ($entity->getChildEntities()->isDirty()) {
    $removed = $entity->getChildEntities()->getDeleteDiff();
    $inserted = $entity->getChildEntities()->getInsertDiff();
}

Also you can get a snapshot of the collection at the moment it was fetched from the database: $entity->getChildEntities()->getSnapshot(); 您还可以在从数据库中获取集合时获取集合的快照: $entity->getChildEntities()->getSnapshot(); , this is used to create the diffs above. ,这用于创建上面的差异。

May be this is not optimal, but it can do the job. 可能这不是最佳,但它可以完成这项工作。 You can add a version field on ParentEntiy with a timestamp, then on each related entity setter function (Child or GranChild) you need to add a line updating that parent timestamp entity. 您可以在ParentEntiy上添加带有时间戳的版本字段,然后在每个相关的实体设置器函数(Child或GranChild)上添加更新该父时间戳实体的行。 In this way each time you call a setter you will produce a change on the parent entity that you can capture at the listener. 这样,每次调用setter时,都会对可以在侦听器处捕获的父实体进行更改。

I have used this solution to update ElasticSearch documents that need to be updated when a change happens on a child entity and it works fine. 我已经使用此解决方案来更新在子实体上发生更改时需要更新的ElasticSearch文档,并且它可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM