Доктрина 2.1 Сохранение сущности в preUpdate lifeCycleCallback - PullRequest
8 голосов
/ 25 октября 2011

Я борюсь со следующим, в классе сущностей у меня есть preUpdate lifeCycleCallback, который должен сохранять новую сущность, прежде чем сбрасывает изменения для auditTrail.

В preRemove и prePersist это работает отлично, но в preUpdate ничего не происходит. Если я сам вызываю flush, он идет по рекурсивному циклу.

По мнению групп Google для пользователей-доктринов, включение этого параметра в onFlush должно быть вариантом, но в этом случае я не могу получить доступ к старым значениям сущности, чтобы сохранить эти старые значения в новой другой сущности для контрольного журнала.

Небольшой пример того, что я пытаюсь архивировать:

<?php
/**
 * @Entity
 * @HasLifeCycleCallbacks
 */
class someEntity {
    ... annotations ...


    /**
     * @PreUpdate
     */
    public function addAuditTrail() {
        $em = \Zend_Registry::get('doctrine')->getEntityManager();

        $entity = new AuditTrail();
        $entity->action = 'update';
        $entity->someField = $this->someField;

        $em->persist($entity); //this just doesn't do anything :-(
    }
}
?>

Это не настоящий код, это просто иллюстрация, которую я хочу. Я тоже попробовал что-то вроде этого:

$em->getUnitOfWork()->computeChangeSet($em->getClassMetaData(get_class($entity)), $entity);

Что должно работать в соответствии с этой темой: http://groups.google.com/group/doctrine-user/browse_thread/thread/bd9195f04857dcd4

Если я снова вызываю сброс, но это вызывает сбой Apache из-за некоторого бесконечного цикла.

Кто-нибудь, кто получил идеи для меня? Спасибо!

Ответы [ 3 ]

6 голосов
/ 13 ноября 2011

Вы никогда не должны использовать диспетчер сущностей внутри своих сущностей. Если вы хотите добавить контрольные журналы, вы должны сопоставить сущность SomeEntity с сущностью AuditTrail и сделать что-то вроде

/**
 * @PreUpdate
 */
public function addAuditTrail() {
    $entity = new AuditTrail();
    $entity->action = 'update';
    $entity->someField = $this->someField;

    $this->autitTrail->add($entity);
}

Если вы установите опцию каскада в отображении, она будет сохраняться при сохранении «SomeEntity».

3 голосов
/ 07 апреля 2013

У меня была такая же проблема в методе preUpdate EventListener. Я решил эту проблему, сохранив новую сущность в свойстве и переместив вызовы persist () и flush () в метод postUpdate.

class someEntity {
... annotations ...

protected $store;

/**
 * @PreUpdate
 */
public function addAuditTrail() {
    //$em = \Zend_Registry::get('doctrine')->getEntityManager();

    $entity = new AuditTrail();
    $entity->action = 'update';
    $entity->someField = $this->someField;

    // replaces $em->persist($entity); 
    $this->store = $entity;
}

/**
 * @PostUpdate
 */
public function saveAuditTrail() {
    $em = \Zend_Registry::get('doctrine')->getEntityManager();
    $em->persist($this->store); 
    $em->flush();
}

}

0 голосов
/ 21 мая 2012

entitymanager-> persist () не будет работать внутри метода preUpdate.Вместо этого вы можете сохранить данные AuditTrail в сеанс и после сброса SomeEntity взять данные из сеанса и выполнить entitymanager-> persist (...) и entitymanager-> flush ()

...