不调用具有抽象基类的Doctrine 2 LifecycleCallbacks

时间:2011-09-06 13:09:56

标签: php doctrine doctrine-orm

我遇到这种情况:

抽象类:     

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实体创建,我可以访问它等。 问题是,从未达到过“死亡('这一点永远不会达到')”这一行。 (注意@ORM \ PreUpdate)这意味着不会调用lifecycleCallbacks 继承的对象。这是一个错误,还是有原因?

7 个答案:

答案 0 :(得分:32)

您的抽象基类必须作为映射超类进行分配,并包含 HasLifecycleCallbacks -Annotation。

更多信息:Inheritance Mapping in the Doctrine Documentation

/**
 * @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.
}

答案 1 :(得分:3)

您必须使用@ORM\HasLifecycleCallbacks注释基类,并使用@ORM\preUpdate

注释函数

您有拼写错误(PreUpdate应该是preUpdate),创建时也不会调用preUpdate(仅在更新时)。因此,如果您希望在创建时也触发它,则应添加@ORM\prePersist

答案 2 :(得分:2)

虽然接受的答复对于一般情况是正确的,但在这种特殊情况下(时间戳),您实际上想要使用学说扩展名Timestampable,例如此处所解释的Lifecycle Callback Issue When Extending FOSUserBundle User Entity

答案 3 :(得分:2)

具有HasLifecycleCallbacks的MappedSuperclass与其子实体位于同一名称空间或目录中非常重要。

当MappedSuperclass位于一个目录(Model)中而实体位于另一个目录(Entity)中时,我遇到了生命周期回调问题。将MappedSuperclass放在与Entities(Entity)相同的目录中解决了这个问题。

答案 4 :(得分:1)

也许我错了,但我认为当你坚持实体时不会触发preUpdate。你应该有一个@prePersist。

http://www.doctrine-project.org/docs/orm/2.0/en/reference/events.html

但是我仍然不确定这会起作用,但你可以试试。另外一个解决方法是覆盖setUpdatedAt函数并调用他的父函数,但这有点难看。

希望@prePersist帮助你。

答案 5 :(得分:1)

也许您可以将此issue report作为参考来设置注释?测试用例似乎有效并且与您的用例相匹配。

答案 6 :(得分:0)

我认为你必须使用@ORM \ HasLifecycleCallbacks

来注释基类

docs