Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 变更集条令事件侦听器中的嵌入文档_Php_Mongodb_Symfony_Doctrine Orm_Embedded Documents - Fatal编程技术网

Php 变更集条令事件侦听器中的嵌入文档

Php 变更集条令事件侦听器中的嵌入文档,php,mongodb,symfony,doctrine-orm,embedded-documents,Php,Mongodb,Symfony,Doctrine Orm,Embedded Documents,我正在使用doctrine的事件侦听器类来实现DB事件的日志记录。我正在使用postUpdate事件。我的mongoDB文档中有一个嵌入式文档。在postUpdate事件中,当我调用$uow->getDocumentChangeSet($entity)方法时,我只获取更改集对象中的更改值。e、 g [0]=> object(Tyre24\ProductBundle\Document\Translations)#1178 (1) { ["translations":protect

我正在使用doctrine的事件侦听器类来实现DB事件的日志记录。我正在使用postUpdate事件。我的mongoDB文档中有一个嵌入式文档。在postUpdate事件中,当我调用
$uow->getDocumentChangeSet($entity)
方法时,我只获取更改集对象中的更改值。e、 g

[0]=>
  object(Tyre24\ProductBundle\Document\Translations)#1178 (1) {
    ["translations":protected]=>
    object(Doctrine\ODM\MongoDB\PersistentCollection)#1216 (10) {
      ["snapshot":"Doctrine\ODM\MongoDB\PersistentCollection":private]=>
      array(0) {
      }
      ["coll":"Doctrine\ODM\MongoDB\PersistentCollection":private]=>
      object(Doctrine\Common\Collections\ArrayCollection)#1217 (1) {
        ["_elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
        array(1) {
          [0]=>
          object(Tyre24\ProductBundle\Document\Translation)#1227 (3) {
            ["key":protected]=>
            string(11) "testkey_new"
            ["language":protected]=>
            string(5) "xx_XX"
            ["value":protected]=>
            string(9) "testvalue"
          }
        }
      }
    }
  }
  [1]=>
  object(Tyre24\ProductBundle\Document\Translations)#1178 (1) {
    ["translations":protected]=>
    object(Doctrine\ODM\MongoDB\PersistentCollection)#1216 (10) {
      ["snapshot":"Doctrine\ODM\MongoDB\PersistentCollection":private]=>
      array(0) {
      }
      ["coll":"Doctrine\ODM\MongoDB\PersistentCollection":private]=>
      object(Doctrine\Common\Collections\ArrayCollection)#1217 (1) {
        ["_elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
        array(1) {
          [0]=>
          object(Tyre24\ProductBundle\Document\Translation)#1227 (3) {
            ["key":protected]=>
            string(11) "testkey_new"
            ["language":protected]=>
            string(5) "xx_XX"
            ["value":protected]=>
            string(9) "testvalue"
          }
        }
      }
    }
  }
}

这里,变更集数组的第一个元素应该反映嵌入文档的旧状态,但它总是在两个数组索引中显示相同的(新)文档。对于没有嵌入文档的文档,它可以正常工作。有什么想法吗?

我不太熟悉ODM(mongo)原则,但我熟悉ORM原则,它们有很多相似之处。我已经建立了类似您为ORM描述的记录器,所以让我分享我的经验

哪些事件以及原因 我喜欢钩住OnFlush事件,因为它是一个单一的时间点,所有写操作都可以在它实际发生之前找到。因此,您可以获得即将发生的一组一致的更改

使用ORM,使用PostPersist、PostUpdate和PostDelete,您可能会迟到,因为更改已经发生,并且无法获得可靠的更改集

使用PrePersist、PreUpdate和PreDelete,您不会得到一个时间点:PreUpdate和PreDelete将发生在刷新操作中,但PrePersist会在您对实体/文档调用
persist()
时立即发生

因此,在OnFlush侦听器中,我将收集所有实体/文档更改以及关联更改。我将把它们保存在内存中,直到PostFlush事件被调度。PostFlush事件发生在将所有内容持久化到数据库之后,因此这是写入日志的安全点。换句话说:当flush操作由于任何原因失败时,日志将不会被写入,因为我们实际上没有保存任何内容

追踪什么 使用ORM,始终可以检测到对标量属性的更改。但对象的更改是通过引用检测的。这意味着,如果属性包含新对象,则会检测到更改。但是,当属性包含相同的对象时(尽管该对象本身已更改),将无法检测到更改

这就是为什么,至少在ORM中,集合已更改的实体不会显示在
$uow->getScheduledEntityInsertions()
等的返回值中。我不确定,但我怀疑ODM的行为方式与此相同

因此,在跟踪侦听器中的更改时,必须使用以下所有方法:

  • $uow->getScheduledDocumentInsertions()
  • $uow->getScheduledDocumentUpserts()
  • $uow->getScheduledDocumentUpdates()
  • $uow->getScheduledDocumentDeletes()
  • $uow->getScheduledCollectionDeletes()
  • $uow->getScheduledCollectionUpdates()
最后两个将返回已更改的集合数组。从集合中,您可以获得拥有的实体/文档(
$col->getOwner()
),并使用diff方法(
$col->getInsertDiff()
$col->getDeleteDiff()
)来查明到底发生了哪些更改


我希望这能帮助您找到解决方案

您找到解决方案了吗?我不确定,但这可能是因为已经在执行更新。能否尝试将侦听器挂接到OnFlush事件?看看这是否会改变结果?此外,这些都是对象,对象始终作为引用传递。由于快照为空且集合包含1项,我可以推迟
$translations
已从包含0项更改为包含1项。在我的情况下,我的侦听器处于刷新状态。我确实更改了对象(它是一个集合,因此我没有添加到现有集合,而是尝试创建一个新集合,并将所有现有项添加到新集合)。