【问题标题】:Symfony 3 / Doctrine - Get changes to associations in entity change setSymfony 3 / Doctrine - 获取实体更改集中关联的更改
【发布时间】:2017-07-16 06:47:05
【问题描述】:

所以我已经知道我可以在preUpdate 生命周期事件中获取对特定实体的更改:

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


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

但是,有没有办法同时获取任何关联实体的更改?例如,假设ParentEntity 的关系设置如下:

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

ChildEntity 也有:

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

有没有办法在preUpdateParentEntity 期间获得所有相关更改?

【问题讨论】:

  • 关联实体本身在preUpdate 中会有自己的变化,除非实体本身保持不变。
  • @JasonRoman 我意识到,但是,我希望在 ParentEntity 上完成所有工作,而不是从每个单独的 preUpdate 逐步构建,这将导致更多代码以及更多的边缘案例。
  • 我发现了类似的东西stackoverflow.com/questions/11748790/…也许有帮助

标签: php symfony doctrine-orm associations


【解决方案1】:

OneToMany 或 ManyToMany 关系中的所有关联实体都显示为 Doctrine\ORM\PersistentCollection

看看 PersistentCollection 的 API,它有一些有趣的公共方法,即使它们被标记为 INTERNAL:https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/PersistentCollection.php#L308

例如,您可以检查您的集合是否脏,这意味着它的状态需要与数据库同步。然后您可以检索已从集合中移除或插入其中的实体。

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

您还可以在从数据库中获取集合时获取集合的快照:$entity->getChildEntities()->getSnapshot();,这用于创建上述差异。

【讨论】:

  • 正是我想要的,我之前找到了这个信息,但不确定它是否适用于我的特定用例 - 你的解释帮助我澄清和扩展了这个概念 - 干杯!
  • 哦,谢谢! 3 年后,它挽救了我的心理健康。
【解决方案2】:

这可能不是最佳的,但它可以完成这项工作。您可以在 ParentEntiy 上添加带有时间戳的版本字段,然后在每个相关的实体设置器函数(Child 或 GranChild)上,您需要添加一行来更新该父时间戳实体。这样,每次调用 setter 时,都会对父实体产生更改,您可以在侦听器处捕获该更改。

我已使用此解决方案来更新 ElasticSearch 文档,当子实体发生更改时需要更新这些文档并且效果很好。

【讨论】:

  • 感谢您提供信息,但我可以为GrandChildEntity$entity->parentEntityChildEntity 执行$entity->childEntity->parentEntity 以访问相关的顶级实体。无论如何,问题仍然是我需要单独的代码来处理对ParentEntityChildEntityGrandChildEntity 的更新,而不是在ParentEntity 更新事件中处理所有这些(并忽略其他相关的更新事件)。
猜你喜欢
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
相关资源
最近更新 更多