Как получить доступ к старым значениям в PrePersist LifecycleCallback в Doctrine2

У меня есть объект в 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++;
    }
}

Ответ 1

Это зависит от того, о каком LifecycleEvent мы говорим. PrePersist и PreUpdate - это разные события.

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 который имеет доступ только к Entity и EntityManager. Теоретически, вы можете получить доступ к UnitOfWork (который отслеживает все изменения в сущностях) через EntityManager, так что вы можете попытаться сделать

$changeSet = $event->getEntityManager()->getUnitOfWork()->getEntityChangeSet(
    $event->getEntity()
);

чтобы получить изменения для сохранения сущности. Затем вы можете проверить этот массив на наличие измененных полей. Однако, поскольку речь идет о вставке, а не об обновлении, я предполагаю, что все поля будут считаться "измененными", и старые значения, скорее всего, будут нулевыми. Я не уверен, это будет работать так, как вам нужно.

Дополнительная ссылка: http://docs.doctrine-project.org/en/2.0.x/reference/events.html