Doctrine 2 LifecycleCallbacks с абстрактным базовым классом не вызывается - PullRequest
15 голосов
/ 06 сентября 2011

У меня такая ситуация:

Абстрактный класс:

abstract class AbstractBase
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     * @var integer
     */
    protected $id;

    /**
     * @ORM\Column(type="datetime", name="updated_at")
     * @var \DateTime $updatedAt
     */
    protected $updatedAt;

    /**
     * @ORM\PreUpdate
     */
    public function setUpdatedAt()
    {
        die('THIS POINT IS NEVER REACHED');
        $this->updatedAt = new \DateTime();
    }
}

Класс бетона:

/**
 * @ORM\Entity(repositoryClass="Entity\Repository\UserRepository")
 * @ORM\Table(name="users")
 * @ORM\HasLifecycleCallbacks
 */
class User extends AbstractBase
{
    // some fields, relations and setters/getters defined here, these all work as expected.
}

Тогда я называю это в моем контроллере так:

$user = $this->em->find('Entity\User', 1);
// i call some setters here like $user->setName('asd');
$this->em->flush();
die('end');

Все работает как положено, поэтому поле id из абстрактного класса создается для объекта User, я могу получить к нему доступ и т. Д. Проблема в том, что строка «die (« ЭТА ТОЧКА НЕ ДОСТИГНУТА »)» никогда не достигается. (Обратите внимание на @ORM \ PreUpdate) Это означает, что lifecycleCallbacks не вызываются унаследованные объекты. Это ошибка, или есть причина для этого?

Ответы [ 7 ]

33 голосов
/ 15 сентября 2011

Ваш абстрактный базовый класс должен быть аннотирован как Сопоставленные суперклассы и включать HasLifecycleCallbacks -Аннотацию.

Дополнительная информация: Отображение наследования в документации доктрины .

/**
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks
 */
abstract class AbstractBase
{
    [...]

    /**
     * @ORM\PreUpdate
     */
    public function setUpdatedAt()
    {
        $this->updatedAt = new \DateTime();
    }
}

/**
 * @ORM\Entity(repositoryClass="Entity\Repository\UserRepository")
 * @ORM\Table(name="users")
 */
class User extends AbstractBase
{
    // some fields, relations and setters/getters defined here, these all work as expected.
}
3 голосов
/ 07 октября 2012

Вы должны аннотировать базовый класс с @ORM\HasLifecycleCallbacks, а функцию с @ORM\preUpdate

У вас есть опечатка (PreUpdate должен быть preUpdate), также preUpdate не вызывается при создании (только при обновлении). Поэтому, если вы хотите, чтобы он также запускался при создании, вы должны добавить @ORM\prePersist.

2 голосов
/ 03 августа 2013

Важно, чтобы MappedSuperclass с HasLifecycleCallbacks находился в том же пространстве имен или каталоге, что и их дочерние сущности.

У меня были проблемы с обратными вызовами жизненного цикла, когда MappedSuperclass находился в одном каталоге (Model), а сущности были в другом (Entity). Помещение MappedSuperclass в тот же каталог, что и Entities (Entity), решило проблему.

2 голосов
/ 29 октября 2012

Хотя принятый ответ является правильным для общего случая, в этом конкретном случае (отметка времени) вы действительно хотите использовать расширение доктрины Timestampable, как описано, например, здесь Проблема обратного вызова жизненного цикла при расширении пользовательского объекта FOSUserBundle

1 голос
/ 13 сентября 2011

Возможно, вы могли бы сообщить о проблеме в качестве справки, как настроить свои аннотации?Кажется, что тестовый сценарий верен и соответствует вашему варианту использования.

1 голос
/ 08 сентября 2011

Может быть, я ошибаюсь, но я не думаю, что preUpdate не срабатывает, когда вы сохраняете сущность. У вас должен быть @ prePersist.

http://www.doctrine -project.org / документы / ОРМ / 2,0 / ен / ссылка / events.html

Но все же тогда я не уверен, что это сработает, но вы можете попробовать это. В противном случае обходным путем может быть перезапись функции setUpdatedAt и просто вызов его родительской функции, но это немного уродливо.

Надеюсь, @prePersist поможет вам.

0 голосов
/ 06 сентября 2011

Я думаю, вы должны аннотировать базовый класс с помощью @ORM \ HasLifecycleCallbacks

документы

...