PreUpdate не запускается

У меня есть этот метод в моей сущности:

/**
     * @ORM\PreUpdate()
     * @ORM\PrePersist()
     */
    public function preStore() {
        if ($this->getPictureFile()) {
            $newFilename = sha1(mt_rand());
            $newFilename = $newFilename . '.' . ($this->getPictureFile()->guessExtension());
            $this->setPictureFilename($newFilename);
        }
    }

И при сохранении объектов все работает отлично, но при обновлении метод вообще не запускается, я тестировал его следующим образом:

/**
     * @ORM\PreUpdate()
     * @ORM\PrePersist()
     */
    public function preStore() { var_dump('asdasdasdadsdasdas');
        if ($this->getPictureFile()) {
            $newFilename = sha1(mt_rand());
            $newFilename = $newFilename . '.' . ($this->getPictureFile()->guessExtension());
            $this->setPictureFilename($newFilename);
        }
    }

И в сохраняющемся var_dump работает, но когда я обновляю объект - это не так. Почему?

Ответ 1

Обновление происходит только в том случае, если изменяется поле объекта (наблюдаемое из доктрины), и поэтому метод preupdate вызывается только после изменения.

Предостережение: я предполагаю, что ваш файл изображения не является доктриной, и так далее, не наблюдаемый доктриной. Таким образом, ваша сущность не изменится для доктрины.

От Как обращаться с файловыми записями с доктриной статья поваренной книги

Обратные вызовы PreUpdate и PostUpdate запускаются только в том случае, если в одном из полей объекта сохраняются изменения. Это означает, что по умолчанию, если вы изменяете только свойство $file, эти события не будут инициироваться, так как само свойство напрямую не сохраняется через Doctrine. Одним из решений было бы использовать обновленное поле, которое сохранялось в Doctrine, и изменять его вручную при изменении файла.

EDIT. Или вы используете Загружаемое поведение расширения доктрины

Ответ 2

Вы должны четко указать доктрине, что ваш объект имеет обратные вызовы lifecycle:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class YourClass

далее вам не понадобится конечная () в ваших аннотациях, если вы не используете какие-либо опции.

/**
 * @ORM\PrePersist
 * @ORM\PreUpdate
 */
public function preStore()

рассмотрите возможность использования прослушивателя/подписчика вместо обращений к жизненному циклу, чтобы упростить повторное использование и очистить ваш объект.

Более подробную информацию можно найти в главе поваренной книги Как регистрировать слушателей и подписчиков событий.

Ответ 3

Я столкнулся с той же проблемой, вот мое решение:

добавьте отображаемое поле updatedAt и просто вызовите setUpdatedAt(new \DateTime()) внутри setter вашего UploadedFile, это вызовет preUpdate-Event для объекта

Ответ 4

Другая причина, по которой это может произойти, - это если у вас есть только одна звездочка

Не удается: /* @ORM\PrePersist */

преуспевает: /** @ORM\PrePersist */

Смешно, но там это..