2016-08-10 2 views
1

Ich habe einen Lebenszyklus-Event. Sobald ein Auftrag erstellt wird, fügt das PrePersist-Lebenszyklusereignis der Bestellung einige weitere Details hinzu, bevor sie in der Datenbank beibehalten werden.Einen Service innerhalb eines Lebenszyklus-Ereignisses aufrufen

Dies ist meine prePersist Ereignisklasse;

<?php 

namespace Qi\Bss\BaseBundle\Lib\PurchaseModule; 

use Qi\Bss\BaseBundle\Entity\Business\PmodOrder; 
use Doctrine\ORM\Event\LifecycleEventArgs; 

/** 
* Listener class 
* Handles events related to list prices 
*/ 
class OrderUserListener 
{ 

    /** 
    * Service container 
    * @var type 
    */ 
    private $serviceContainer; 

    /** 
    * Performs tasks before destruction 
    * @ORM\PrePersist 
    */ 
    public function prePersist(LifecycleEventArgs $args) 
    { 
     $order = $args->getEntity(); 

     if ($order instanceof PmodOrder) { 
      $user = $this->serviceContainer->get('security.token_storage')->getToken()->getUser(); 

      if ($user) { 
       $order->setCreatedBy($user); 
       $order->setCreatedAt(new \DateTime(date('Y-m-d H:i:s'))); 
       $order->setDepartment($user->getDepartment()); 
       $order->setStatus(PmodOrder::STATUS_AWAITING_APPROVAL); 

       $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created'); 
      } 
     } 
    } 

    /** 
    * Sets the sales order exporter object 
    * @param type $serviceContainer 
    */ 
    public function setServiceContainer($serviceContainer) 
    { 
     $this->serviceContainer = $serviceContainer; 
    } 
} 

Es funktioniert perfekt, aber dieser Teil $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created'); will nicht arbeiten. Ich versuche, einen Dienst darin zu nennen. Ich weiß, dass der Service in meinen Controllern perfekt funktioniert, aber hier bekomme ich einen Fehler.

Eine neue Einheit wurde durch die Beziehung 'Qi \ Bss \ BaseBundle \ Entity \ Geschäft \ PmodLog # Ordnung' gefunden, die bestehen bleiben für Unternehmen Operationen Kaskade nicht konfiguriert war: Nuwe Test-vir Logger. Um dieses Problem zu lösen: Rufen Sie entweder EntityManager # persist() auf dieser unbekannten Entität explizit auf oder konfigurieren Sie die Kaskade persistent diese Zuordnung im Mapping zum Beispiel @ManyToOne (.., cascade = {"persist"}).

So sieht meine OrderLogger Serviceklasse aus;

Ich habe bereits versucht, die persist in meinem Protokoll zu fusionieren, aber das funktioniert auch nicht. Kann jemand bitte helfen und erklären, was ich falsch mache?

+0

Ihr Dienst sollte '' $ em-> flush() '' nicht in einem prePersist-Ereignis aufrufen. – Alsatian

+0

Nicht sicher, aber versuchen Sie '' $ args -> getEntityManager() '' an die Protokollmethode anstelle der Konstruktorinjektion für den EntityManager zu übergeben. – Alsatian

+0

@Alsatian Ich verstehe nicht 100%, muss den Flush von meinem Dienst entfernen? Aber dann wird es nicht in meinen Controllern funktionieren, wo ich den gleichen Dienst anrufe. Ich brauche es in einem Controller und in meinem PrePersist-Event. –

Antwort

0

Ich reparierte das problem, indem ich einen postPersist hinzufüge und den logger dort anstatt in meinem prePersist anrufe;

/** 
* Performs tasks before destruction 
* @ORM\PostPersist 
*/ 
public function postPersist(LifecycleEventArgs $args) 
{ 
    $order = $args->getEntity(); 

    if ($order instanceof PmodOrder) {     
     $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created'); 
    } 
} 

Weil das, was ich denke, passiert ist, dass der Logger ausgeführt werden versucht, aber die Reihenfolge, in dem Logger noch nicht existiert, da es noch nicht ist, beibehalten. Dieser Weg macht mehr Sinn für mich, und ich denke, das ist die einfachste Lösung. Ich könnte mich irren, Kommentare und andere Meinungen zu meiner Antwort sind willkommen.

0

Dies ist nicht die beste Architektur, aber es wird funktionieren:

Auf PrePersist alle Nachrichten eine Art private Variable hinzufügen (wie $ LogMessages), und fügen Sie ein weiteres Ereignis

/** 
* @param PostFlushEventArgs $args 
*/ 
public function postFlush(PostFlushEventArgs $args) 
{ 
    $logMessages = $this->logMessages; 

    $this->logMessages = array(); //clean to avoid double logging 

    if (!empty($logMessages)) { 
     foreach ($logMessages as $message) { 
      $this->serviceContainer->get('bss.pmod.order_logger')->log($message); 
     } 

    } 
} 
Verwandte Themen