Symfony 缓存组件和延迟加载
Symfony Cache Component and Lazy Loading
我正在使用 Symfony 3.2 的缓存组件。
我有一个名为 MenuItem 的实体,它与其他实体具有多对一关系:
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 中的实体 ProductCategory 是代理,如您所见:
5 => MenuItem {#3428 ▼
#id: 3
#name: "Vinils"
#weight: 60
#selector: "vinil"
-categoryCollection: ProductCategory {#3429 ▼
+__isInitialized__: false
#id: 23
#name: ""
如果我调用 getName()
它 returns "" 而不是产品类别名称(延迟加载不起作用)。
我不明白这种行为,所以如果有人能解释我,我会很高兴,因为延迟加载不起作用(我想我可以配置与 fetch="EAGER"
的关系来避免这个问题)。
谢谢。
这是 "entity not managed" 的常见副作用,发生这种情况是因为在从缓存 ($menuItems = $menuItemsCached->get()
) 中检索所有菜单项后,您的缓存实体超出了实体管理器的范围,因此相关代理是"dead".
您只需将每个缓存的实体合并到当前实体管理器,代理将再次 "live":
$menuItems = $menuItemsCached->get();
foreach ($menuItems as &$menuItem) {
$menuItem = $entityManager->merge($menuItem);
}
以后就可以偷懒获取每个商品分类的名称了
我正在使用 Symfony 3.2 的缓存组件。 我有一个名为 MenuItem 的实体,它与其他实体具有多对一关系:
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 中的实体 ProductCategory 是代理,如您所见:
5 => MenuItem {#3428 ▼
#id: 3
#name: "Vinils"
#weight: 60
#selector: "vinil"
-categoryCollection: ProductCategory {#3429 ▼
+__isInitialized__: false
#id: 23
#name: ""
如果我调用 getName()
它 returns "" 而不是产品类别名称(延迟加载不起作用)。
我不明白这种行为,所以如果有人能解释我,我会很高兴,因为延迟加载不起作用(我想我可以配置与 fetch="EAGER"
的关系来避免这个问题)。
谢谢。
这是 "entity not managed" 的常见副作用,发生这种情况是因为在从缓存 ($menuItems = $menuItemsCached->get()
) 中检索所有菜单项后,您的缓存实体超出了实体管理器的范围,因此相关代理是"dead".
您只需将每个缓存的实体合并到当前实体管理器,代理将再次 "live":
$menuItems = $menuItemsCached->get();
foreach ($menuItems as &$menuItem) {
$menuItem = $entityManager->merge($menuItem);
}
以后就可以偷懒获取每个商品分类的名称了