2017-07-11 3 views
1

Ich verwende die Cache-Komponente für Symfony 3.2. Ich habe eine Entität MenuItem genannt, die eine viele zu einer Beziehung zu anderen hat:Symfony Cache Component und Lazy Loading

class MenuItem 
{ 
    //... 

    /** 
    * @ORM\ManyToOne(targetEntity="BaseBundle\Entity\ProductCategory") 
    * @ORM\JoinColumn(name="category_id", referencedColumnName="id") 
    */ 
    private $category; 

    //... 

In einem Service, möchte ich alle menuitems abzurufen und sie im Cache speichern:

$menuItemsCached = $this->cache->getItem('app.menu_items'); 
    if ($menuItemsCached->isHit()) { 
     $menuItems = $menuItemsCached->get(); 
    } else { 
     $repository = $this->em->getRepository('WebBundle:MenuItem'); 
     $menuItems = $repository->findBy([], ['weight' => 'ASC']); 
     $menuItemsCached->set($menuItems); 
     $this->cache->save($menuItemsCached); 
    } 
    return $menuItems; 

Die Problem ist, dass, wenn ich das Array aus dem Cache erhalten, die Entitäten Product in meinem MenuItems sind Proxies wie Sie sehen können:

5 => MenuItem {#3428 ▼ 
    #id: 3 
    #name: "Vinils" 
    #weight: 60 
    #selector: "vinil" 
    -categoryCollection: ProductCategory {#3429 ▼ 
     +__isInitialized__: false 
     #id: 23 
     #name: "" 

Und wenn ich angerufen getName() gibt "" stattdessen den Namen der Produktkategorie zurück (Lazy Loading funktioniert nicht).

Ich verstehe dieses Verhalten nicht, also würde ich sehr angenehm sein, wenn mir jemand erklären kann, weil Lazy Loading nicht funktioniert (ich nehme an, ich kann die Beziehung mit konfigurieren, um dieses Problem zu vermeiden).

Danke.

Antwort

2

Es ist eine häufige Nebenwirkung von „Einheit nicht geschafft“, dies geschieht, weil die zwischengespeicherten Entitäten nur nach außerhalb des Bereichs von Entity-Manager sind ruft alle Menüpunkte aus dem Cache ($menuItems = $menuItemsCached->get()) daher die entsprechenden Proxies sind „tot“ .

Alles, was Sie brauchen, ist jedes zwischengespeichert Einheit der aktuellen Entität Manager fusionieren und die Proxys wird „leben“ wieder:

$menuItems = $menuItemsCached->get(); 
foreach ($menuItems as &$menuItem) { 
    $menuItem = $entityManager->merge($menuItem); 
} 

Später Sie wäre in der Lage, den Namen der einzelnen Produktkategorien erhalten in ein fauler Weg.