Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 preUpdate event - not triggered on insert?

Tags:

php

doctrine

I have a bunch of entities with both a date_created and date_modified field, and I'm attempting to have these fields automatically set themselves on insert or update. date_created is only set at insert, but date_modified is set at both insert or update.

I have a method in my entity class with a @PreUpdate annotation, but it only seems to get called when an entity is updated. It is not called when a new entity is inserted. The documentation says this about the preUpdate event:

"The preUpdate event occurs before the database update operations to entity data."

Is this correct behavior? If so, what is the best way to have a method called before both update or insert? Currently if I tag the method with both @PreUpdate and @PrePersist then it works, but I'm not sure if this is optimal:

/**
 * @PreUpdate
 * @PrePersist
 */
public function beforeSave()
{
    if (!$this->getCreatedAt()) {
        $this->setCreatedAt(new \DateTime());
    }
    $this->setModifiedAt(new \DateTime());
}
like image 358
Harold1983- Avatar asked Sep 20 '10 19:09

Harold1983-


People also ask

What is the event system in doctrine 2?

Doctrine 2 features a lightweight event system that is part of the Common package. Doctrine uses it to dispatch system events, mainly lifecycle events . You can also use it for your own custom events. 9.1. The Event System ¶ The event system is controlled by the EventManager. It is the central point of Doctrine’s event listener system.

What is the difference between doctrine subscribers and listeners in Symfony?

Symfony loads (and instantiates) Doctrine listeners only when the related Doctrine event is actually fired; whereas Doctrine subscribers are always loaded (and instantiated) by Symfony, making them less performant. Entity listeners are defined as PHP classes that listen to a single Doctrine event on a single entity class.

How to trigger the prepersist event for cascaded associations?

There are two ways for the prePersist event to be triggered. One is obviously when you call EntityManager#persist (). The event is also called for all cascaded associations. There is another way for prePersist to be called, inside the flush () method when changes to associations are computed and this association is marked as cascade persist.


1 Answers

Persist and Update are 2 different events so if you want the callback to be applied for them both then you'll need both annotations. It may satisfy your misgivings to instead create two methods:

/**
 * @PrePersist
 */
public function beforePersist()
{
    $this->setCreatedAt(new \DateTime());        
    $this->setModifiedAt(new \DateTime());
}

/**
 * @PreUpdate
 */
public function beforeUpdate()
{        
    $this->setModifiedAt(new \DateTime());
}
like image 178
rojoca Avatar answered Oct 04 '22 01:10

rojoca