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

2022-01-03 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.

我发现这篇文章很相似,但这种方法并没有解决我的问题:Doctrine detaching, caching,并合并

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 时,它会被标记为脏的.这意味着当执行刷新时,实体将在数据库中更新.这对我来说似乎是合理的,因为当您创建一个实体 managed 时,您实际上希望 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.

相关文章