2013-01-24 22 views
5

Şu anda yüklendiğinde hafifçe değiştirmek istediğim bir varlığa sahibim. Bu değişiklik, varlık ile birlikte yeni bir alanda sürdürülecek olan tek seferlik bir değişiklik olacaktır.Doctrine postIlişkiler için yedek olay

Geçerli hedefimi açıklığa kavuşturmak için: Varlık bir "Konum" dur ve iç içe geçmiş kümenin bir parçasını oluşturur. Bir adı, lft/rgt değerleri ve bir kimliği vardır. Bu varlık ile yaptığım hesaplama açısından pahalı bir görev, tam bir konum yolunu getirip metin olarak göstermekti. Örneğin, konum bilgisi olan "Waterloo" ile "Waterloo | London | United Kingdom" olarak göstermek istiyorum. Bu, tüm kümede (kök düğüme) geçişi içerir.

Bunun maliyetini azaltmak için, Konum öğesinde bu değerle damgalanabilecek (ve/veya yer (veya ağacın içindeki herhangi bir konumun adı değiştirildiyse) güncelleştirilebilen yeni bir alan oluşturdum. Uygulamamın canlı bir durumda olduğunu düşünürsek, DB'de oldukça yoğun bir kerelik bir isabetle karşılaşacağından, bunu tek bir işlem olarak kullanmaktan kaçınmam gerekir. Bunun yerine, bu güncelleştirmeyi her konum için (ve bu değer) yüklenir. Doctrine'nin postLoad olay mekanizmasının bunu başarmak için mükemmel olacağını düşünmüştüm, ancak bu ...

Konum varlıkları doğrudan uygulamam tarafından yüklenmiyor, her zaman bir ilişkinin ters tarafı olacaklar. Bu aklın ve öğretinin yükleme sonrası olay gerçektir olarak:

  • yüklemez mu
  • sadece sahibi varlıkları

Ben yolu yoktur için ateş mı herhangi bir ilişkili veriler (erişime izin) hafifçe bu değişikliklerin yapılması.

Bu konuda herhangi bir tavsiye veya deneyiminiz var mı?

+0

Kişisel bir tavsiye olarak, kalıcılık katmanındaki süslü mantıkla bunu başaramazdım. Bunun yerine, varlığınıza yapılan çağrıları proxy yapan ve sonunda ana öğeleri almayı başaran bir toplu model oluşturun. Bu servis katmanınıza uyacak – Ocramius

cevap

5

PostLoad olayındaki ilişkili Konum nesnelerini Entity Manager'daki initializeObject() yöntemini kullanarak yükleyebildim.

/** 
* Upon loading the object, if the location text isn't set, set it 
* @param \Doctrine\ORM\Event\LifecycleEventArgs $args 
*/ 
public function postLoad(\Doctrine\ORM\Event\LifecycleEventArgs $args) 
{ 
    $this->em = $args->getEntityManager(); 
    $entity = $args->getEntity(); 

    if ($entity instanceof \Entities\Location) 
    { 
     if (is_null($entity->getPathText())) 
     { 
      $entity->setPathText("new value"); 
      $this->em->flush($entity); 
     } 
    } elseif ($entity instanceof {parent Entity}) 
    { 
     $location = $entity->getLocation(); 
     // This triggers the postLoad event again, but this time with Location as the parent Entity 
     $this->em->initializeObject($location); 
    } 
}