2011-10-25 14 views
8

Mam walkę z następującymi, w klasie encji mam preUpdate lifeCycleCallback, który musi przetrwać nowy podmiot, zanim opróżni zmiany dla audytuTrail.Doctrine 2.1 Persist entity w preUpdate lifeCycleCallback

W preRemove i PrePersist działa to idealnie, ale w trybie przed aktualizacją nic się nie dzieje. Jeśli zadzwonię do flusha, przechodzi on w pętlę rekursywną.

Zgodnie z grupami dyskusyjnymi Google dla użytkownika doktryny umieszczenie go w OnFlush powinno być opcją, ale w takim przypadku nie mogę uzyskać dostępu do starych wartości obiektu, aby zapisać stare wartości w nowym obiekcie dla audittrail.

Jakiś mały przykład tego, co staram się archiwum:

<?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 :-(
    } 
} 
?> 

To nie jest prawdziwy kod, po prostu coś, aby zilustrować, co chcę. Próbowałem też coś takiego:

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

Które powinny pracować według tego tematu: http://groups.google.com/group/doctrine-user/browse_thread/thread/bd9195f04857dcd4

Gdybym ponownie wywołać rumieniec, ale powoduje, że Apache upaść z powodu jakiejś nieskończonej pętli.

Ktoś, kto ma pomysły dla mnie? Dzięki!

Odpowiedz

6

Nigdy nie powinieneś używać uprawnienia do zarządzania w swoich jednostkach. Jeśli chcesz dodać ścieżki audytu, należy zmapować „SomeEntity” podmiotu do podmiotu „ścieżka audytu” i zrobić coś jak

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

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

Jeśli ustawisz opcję Kaskada na mapowaniu, będzie się utrzymywał, kiedy persist "SomeEntity".

+0

Dlaczego nie należy użyć menedżera jednostki wewnątrz mojego podmioty? A jeśli odwzorujesz AuditEntity na SomeEntity, to zostanie on powiązany z bazą danych i nie jest to tym, co chcę skopiować moje jednostki i dodać inne pola, takie jak "action" = update itd. To AuditEntity było tylko przykładem, ponieważ do audytu używam : https://github.com/keesschepers/EntityAudit –

+0

Używałbym eventmanager. Chciałam rzucić okiem na twój kod, ale nie ma jeszcze czasu. – tvlooy

+1

W końcu (rok temu!) Użyłem menedżera zdarzeń (EventSubscriber) do wykonywania tych zadań na całym świecie. Zawarłem to w mojej strukturze: https://github.com/php-pike/Pike (spójrz na część EntityAudit) dzięki! –

0

tryb uprawnienia dochodystodawcy-> persist() nie działa w metodzie preUpdate. Zamiast tego można zapisać dane z AuditTrail w sesji i po spłukaniu "SomeEntity", pobrać dane z sesji i wykonać funkcję employeemanager-> persist (...) i employeemanager-> flush()

3

Miałem ten sam problem w metodzie preUpdate obiektu EventListener. Rozwiązałem to, przechowując nowy obiekt w obiekcie i przenosząc nowe wywołania persist() i flush() do metody 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

Wiem, że wydaje się lekko "hack like", ale nie widzę "oficjalne" rozwiązanie tego przypadku użycia, ja też użyłem tej metody –

+1

Niestety, wywoływanie 'flush()' wewnątrz wywołania zwrotnego cyklu życia nie jest obsługiwane przez Doctrine i nie działa to w nowszych wersjach Doctrine; Otrzymuję ten błąd: http://www.doctrine-project.org/jira/browse/DDC-3218. –

+0

Zobacz ten link, aby dowiedzieć się, jak to zrobić poprawnie: http://stackoverflow.com/questions/16904462/adding-dodatkowe-persist-calls-do-preupdate-all-in-symfony-2-1. Szkoda, że ​​nie było sposobu, aby zrobić to wewnątrz klasy jednostek, zamiast tworzyć osobną klasę globalną ... –

Powiązane problemy