Doctrine 2 - 如何在关系中使用从缓存中检索到的对象

2022-01-16 00:00:00 caching php symfony doctrine doctrine-orm

我正在从事一个在 Symfony 2 中使用 Doctrine 2 的项目,我使用 MEMCACHE 来存储教义的结果.我对从 MEMCACHE 检索到的对象有疑问.

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 in entity ContestRegistry
 * @var contest
 * 
 * @ORMManyToOne(targetEntity="Contest", inversedBy="usersRegistered")
 * @ORMJoinColumn(name="contest_id", referencedColumnName="id", onDelete="CASCADE"))
 *
 */
protected $contest;

在其他实体中

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

现在假设 Contest 在缓存中,我想保存一个 ContestRegistry 条目.所以我在缓存中检索对象竞赛如下:

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();

我的问题是,学说正确保存了新实体,但它也更新了实体 Contest 并更新了更新的列.真正的问题是它对每个条目进行更新查询,我只想添加对实体的引用.我怎样才能使它成为可能?任何帮助将不胜感激.

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.

推荐答案

为什么

当一个实体被合并回 EntityManager 时,它将被标记为脏.这意味着当执行刷新时,实体将在数据库中更新.这对我来说似乎很合理,因为当您创建一个实体托管时,您实际上希望 EntityManager 来管理它;)

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.

使用参考

所以不要将 $contest 合并回 EntityManager,而是获取对它的引用:

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();

该引用将是一个代理(除非它已经托管),并且根本不会从数据库加载(即使在刷新 EntityManager 时也不会).

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).

结果缓存

您可以使用 Doctrine 的 结果缓存.它缓存查询结果以防止访问数据库,但(如果我没记错的话)仍然会补充这些结果.这可以防止您在缓存实体本身时遇到的许多问题.

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.

相关文章