Doctrine 2 - 如何使用从缓存中检索的对象在关系中 [英] Doctrine 2 - How to use objects retrieved from cache in relationships

查看:97
本文介绍了Doctrine 2 - 如何使用从缓存中检索的对象在关系中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个在Symfony 2中使用Doctrine 2的项目,我使用MEMCACHE来存储学说的结果。
我从MEMCACHE检索的对象有一个问题。



我发现这个帖子类似,但是这种方法不能解决我的问题:教义拆卸,缓存和合并



这个是场景

  / ** 
*这是在实体ContestRegistry
* @var比赛
*
* @ ORM\ManyToOne(targetEntity =Contest,inversedBy =usersRegistered)
* @ ORM\JoinColumn(name =contest_id,referencedColumnName =id,onDelete =CASCADE))
*
* /
protected $ contest;

和其他实体

  / ** 
* @var usersRegistered
*
* @ ORM\OneToMany(targetEntity =ContestRegistry,mappedBy =contest)
*
* /
protected $ usersRegistered;

现在想象大赛正在缓存,我想保存一个ContestRegistry项。
所以我检索缓存中的对象比赛如下:

  $ contest = $ cacheDriver-> fetch($键); 
$ contest = $ this-> getEntityManager() - > merge($ contest);
return $ contest;

作为最后一个操作,我做:

  $ contestRegistry = new ContestRegistry(); 
$ contestRegistry-> setContest($ contest);
$ this-> entityManager-> persist($ contestRegistry);
$ this-> entityManager-> flush();

我的问题是,这个教义正确地保存了新的实体,而且还对实体进行了更新并更新列更新。真正的问题是它为每个条目进行更新查询,我只想添加对实体的引用。
我怎么可以使它成为可能?
任何帮助将不胜感激。

解决方案

为什么



当实体合并回EntityManager时,它将被标记为脏。这意味着当执行刷新时,实体将在数据库中更新。这对我来说似乎是合情合理的,因为当您使用实体管理时,您实际上希望EntityManager管理它;)



在您的情况下只需要与另一个实体进行关联的实体,因此您不需要真正需要管理。



使用参考



所以,将 $ contest 合并到EntityManager中,但可以引用它:

  $ contest = $ cacheDriver-> fetch($ key); 
$ contestRef = $ em-> getReference('Contest',$ contest-> getId());

$ contestRegistry = new ContestRegistry();
$ contestRegistry-> setContest($ contestRef);

$ em-> persist($ contestRegistry);
$ em-> flush();

该引用将是一个代理(除非已经被管理),将不会从数据库加载(甚至在刷新EntityManager时)。



结果缓存



代替使用您自己的缓存机制,您可以使用Doctrine的结果缓存。它缓存查询结果,以防止数据库的访问,但(如果我没有错误)仍然水合这些结果。这样可以防止您本身可以使用缓存实体获得很多问题。


I'm working in a project that use Doctrine 2 in Symfony 2 and I use MEMCACHE to store doctrine's results. I have a problem with objects that are retrieved from MEMCACHE.

I found this post similar, but this approach not resolves my problem: Doctrine detaching, caching, and merging

This is the scenario

/**
 * This is in entity ContestRegistry
 * @var contest
 * 
 * @ORM\ManyToOne(targetEntity="Contest", inversedBy="usersRegistered")
 * @ORM\JoinColumn(name="contest_id", referencedColumnName="id", onDelete="CASCADE"))
 *
 */
protected $contest;

and in other entity

 /**
 * @var usersRegistered
 * 
 * @ORM\OneToMany(targetEntity="ContestRegistry", mappedBy="contest")
 *
 */
protected $usersRegistered;

Now imagine that Contest is in cache and I want to save a ContestRegistry entry. So I retrieve the object contest in cache as follows:

$contest = $cacheDriver->fetch($key);
$contest = $this->getEntityManager()->merge($contest);
return $contest;

And as last operation I do:

$contestRegistry = new ContestRegistry();
$contestRegistry->setContest($contest);
$this->entityManager->persist($contestRegistry);
$this->entityManager->flush();

My problem is that doctrine saves the new entity correctly, but also it makes an update on the entity Contest and it updates the column updated. The real problem is that it makes an update query for every entry, I just want to add a reference to the entity. How I can make it possible? Any help would be appreciated.

解决方案

Why

When an entity is merged back into the EntityManager, it will be marked as dirty. This means that when a flush is performed, the entity will be updated in the database. This seems reasonable to me, because when you make an entity managed, you actually want the EntityManager to manage it ;)

In your case you only need the entity for an association with another entity, so you don't really need it to be managed. I therefor suggest a different approach.

Use a reference

So don't merge $contest back into the EntityManager, but grab a reference to it:

$contest    = $cacheDriver->fetch($key);
$contestRef = $em->getReference('Contest', $contest->getId());

$contestRegistry = new ContestRegistry();
$contestRegistry->setContest($contestRef);

$em->persist($contestRegistry);
$em->flush();

That reference will be a Proxy (unless it's already managed), and won't be loaded from the db at all (not even when flushing the EntityManager).

Result Cache

In stead of using you own caching mechanisms, you could use Doctrine's result cache. It caches the query results in order to prevent a trip to the database, but (if I'm not mistaken) still hydrates those results. This prevents a lot of issues that you can get with caching entities themselves.

这篇关于Doctrine 2 - 如何使用从缓存中检索的对象在关系中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆