2017-07-11 170 views
1

我为Symfony 3.2使用缓存组件。 我有一个名为菜单项是与其他多对一关系的实体:Symfony缓存组件和延迟加载

class MenuItem 
{ 
    //... 

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

    //... 

在服务,我想检索所有的菜单项,并将其保存在缓存中:

$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; 

的问题是,当我从缓存阵列,实体产品分类里面我的MenuItems是代理,你可以看到:

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

如果我叫getName()它返回“”而不是产品类别名称(延迟加载不起作用)。

我不明白这个行为,所以我会非常愉快的,如果任何人可以解释我,因为懒加载不工作(我想我可以配置与fetch="EAGER",以避免这个问题的关系)。

谢谢。

回答

2

它的“实体不管理”常见的副作用,出现这种情况是因为您的缓存的实体超出范围从实体管理器后立即从缓存中检索($menuItems = $menuItemsCached->get())所有菜单项,因此相关的代理是“死”

所有你需要的是合并的每个高速缓存的实体为当前实体管理器和代理将再次“活”

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

之后,你就可以得到每个产品类别的名称一种懒惰的方式。