Php 原则2:未变更实体的强制更新计划

Php 原则2:未变更实体的强制更新计划,php,mysql,zend-framework,doctrine-orm,Php,Mysql,Zend Framework,Doctrine Orm,在没有实际更改任何属性的情况下,如何安排手动更新实体 我尝试了$entityManager->getUnitOfWork()->scheduleForUpdate($entity),但它在内核中给出了一个错误,并且我没有调试的意图 如果实体是重要的,则对其进行管理:$entity=$repository->findOne(1) 我需要这个,以便在flush()上调用我的EventSubscriber 我也尝试过类似于$entityManager->getEventManager()->dispa

在没有实际更改任何属性的情况下,如何安排手动更新实体

我尝试了
$entityManager->getUnitOfWork()->scheduleForUpdate($entity)
,但它在内核中给出了一个错误,并且我没有调试的意图

如果实体是重要的,则对其进行管理:
$entity=$repository->findOne(1)

我需要这个,以便在
flush()
上调用我的
EventSubscriber

我也尝试过类似于
$entityManager->getEventManager()->dispatchEvent(\doctor\ORM\Events::preUpdate)
,但是我的侦听器的
preUpdate()
接收
EventArgs
而不是
PreUpdateEventArgs


感谢您的帮助

目标是什么?如果没有更改属性,为什么要计划更新?

解决方案有点粗糙,但我可以通过执行以下操作来实现这一点

$objectManager->getUnitOfWork()->setOriginalDocumentData($object, array('__fake_field'=>'1'));
这本质上导致条令认为文档已从原始文档更改,并将其计算为更改,从而导致事件在刷新时执行

本例是针对MongoODM解决方案的,但同样的技术也适用于ORM,如下所示

$objectManager->getUnitOfWork()->setOriginalEntityData($object, array('__fake_field'=>'1'));

Wpigott提到的方法不适用于我(至少在doctrine/orm v2.4.2中是这样),我使用的是:

$entityManager->getUnitOfWork()->setOriginalEntityProperty(spl_object_hash($entity), 'field_name', '__fake_value__');

其中
field\u name
existing property name.

尽管这个问题有点老了,我还是找到了一种更优雅的方法来解决这个问题,我想在这里使用ORM 2.6.2:

您可以简单地告诉表的
ClassMetadataInfo
对象,将传递给
UnitOfWork
propertyChanged
函数的字段声明为脏字段。这里的重要部分是设置更改跟踪策略属性更改调用:

$unitOfWork = $entityManager->getUnitOfWork();
$classMeta  = $entityManager->getClassMetadata('Your\Table\Class');
$ctp        = $classMeta->changeTrackingPolicy; # not a function but a variable

# Tell the table class to not automatically calculate changed values but just
# mark those fields as dirty that get passed to propertyChanged function
$classMeta->setChangeTrackingPolicy(ORM\ClassMetadataInfo::CHANGETRACKING_NOTIFY);

# tell the unit of work that an value has changed no matter if the value
# is actually different from the value already persistent
$oldValue = $entity->getValue('fieldName'); # some custom implementation or something
$newValue = $oldValue;
$unitOfWork->propertyChanged($entity, 'fieldName', $oldValue, $newValue);

# field value will be updated regardless of whether its PHP value has actually changed
$entityManager->flush();

# set the change tracking policy back to the previous value to not mess things up
$classMeta->setChangeTrackingPolicy($ctp);
您可能还需要查看
原则\Common\NotifyPropertyChanged
界面


我希望这对某人有用。

这样做是有正当理由的。例如,如果您有一些侦听器在数据持久化之前对其进行修改,则需要执行迁移。这允许您加载并刷新每个文档,并允许侦听器更改数据以实现持久性。我的用例是加密迁移。您可以在另一个示例中看到:我在实体的更新时间对响应进行缓存。我不仅需要在更新实体时使缓存过期,还需要在更新其相关子项时使缓存过期。因此,这是一个合理的问题。虽然我不太喜欢这些答案:)我现在不能真正测试这个,但我很确定只要条令不进行额外的完整性检查,它就会起作用。如果它在实体结构旁边抛出这个,它将被删除,并且没有任何区别。你能证实它对你有用吗?我能证实它对我有用。我也在tdm/doctrine加密包中实现了它。和。仍在编写文档,但您知道它是如何进行的。