我在Doctrine2中有一个实体,并将HasLivecycleCallbacks与PrePersist一起使用。一般来说,这工作正常,但我想更改版本,当我的实体中的某些字段更改。我有机会获得旧的价值观吗?或者只是已更改的键?
/**
* @ORM\HasLifecycleCallbacks
*/
class Person {
/**
* @PrePersist
* @PreUpdate
*/
public function increaseVersion() {
if ( $this->version == null ) {
$this->version = 0;
}
// only do this, when a certain attribute changed
$this->version++;
}
}
答案 0 :(得分:24)
这取决于我们正在谈论的LifecycleEvent。 PrePersist and PreUpdate are different events.
在实体更新之前,会先触发 PreUpdate 。这将为您提供一个PreUpdateEventArgs
对象,它是一个扩展的LifecycleEventArgs
对象。这将允许您查询已更改的字段,并允许您访问旧值和新值:
if ($event->hasChangedField('foo')) {
$oldValue = $event->getOldValue('foo');
$newValue = $event->getNewValue('foo');
}
您还可以通过getEntityChangeSet()
获取所有更改的字段值,这样可以为您提供如下数组:
array(
'foo' => array(
0 => 'oldValue',
1 => 'newValue'
),
// more changed fields (if any) …
)
另一方面, PrePersist 会假设一个新的实体(想想插入新行)。在PrePersist中,您将获得一个LifecycleEventArgs
对象,该对象只能访问实体和EntityManager
。从理论上讲,您可以通过EntityManager
访问UnitOfWork
(跟踪实体的所有更改),以便您可以尝试
$changeSet = $event->getEntityManager()->getUnitOfWork()->getEntityChangeSet(
$event->getEntity()
);
获取要保留的实体的更改。然后,您可以检查此数组是否有更改的字段。但是,由于我们讨论的是插入而不是更新,我假设所有字段都被视为“已更改”,旧值可能全部为空。我不确定,这会在您需要的时候起作用。
进一步参考:http://docs.doctrine-project.org/en/2.0.x/reference/events.html