Doctrine merge:DateTime字段总是更新 [英] Doctrine merge: DateTime field always updated

查看:114
本文介绍了Doctrine merge:DateTime字段总是更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用现有的 Id 创建一个新的实体,我想更新相关的数据库记录。

I create a new Entity with an existing Id, and I want to update the related database record.

学说合并
一直是我最好的朋友:识别是否有更改并生成正确的更新查询。

Doctrine merge has been my best friend: recognizes if there are changes and generates the correct update query.

$entity = new Entity();
$entity->setId(1);
$entity->setName('test');
$EntityManager->merge($entity);
$EntityManager->flush();

假设id = 1的元素已经存在于db中:如果名称不同'test',Doctrine生成这个查询:

Suppose that the element with the id=1 already exists in the db: if the name is different from 'test', Doctrine generates this query:

UPDATE table SET name = ? WHERE id = ? ["test","1"]

如果我再次运行上面的代码,Doctrine承认没有被更改,并且不会提交任何查询。

If I run again the code above, Doctrine recognizes that nothing is changed, and no query is committed.

但是... 当我设置一个DateTime字段时,Doctrine将其视为已更改,并始终运行更新查询:

But... when I set a DateTime field, Doctrine consider it as changed and always runs the update query:

$entity = new Entity();
$entity->setId(1);
$entity->setDate(new \DateTime(2000-01-01));
$EntityManager->merge($entity);
$EntityManager->flush();
//* ALWAYS commits this query:
>> UPDATE table SET date = ? WHERE id = ? ["2000-01-01 00:00:00","1"]

你知道吗一种避免这种无用的更新的方法?谢谢!

Do you know a way to avoid this useless update? Thanks!

推荐答案

正如@Raymond所说,这是预期的行为。

As said by @Raymond, it's the expected behavior.

可惜的是,如果您的合并不依赖于日期属性,则可以通过以下方式设置合并后的日期:

It's a pity, but if your merge doesn't depend on the date property, a workaround could be to set the date after the merge like this:

$entity = new Entity();
$entity->setId(1);
// Set all fields that the merge is depending on
// ...
$EntityManager->merge($entity);

$entity->setDate(new \DateTime('2000-01-01'));
$EntityManager->flush();

更新

尝试后,唯一的选择似乎是检索合并对象,并通过再次刷新EntityManager进行更新。

After tried, the only alternative seems to retrieve the merged object and update it by flushing the EntityManager again.

您可以使用:

$entity = new Entity();
$entity->setId(1);
// Set all fields that the merge is depending on
$EntityManager->merge($entity);
$EntityManager->flush();

$entity = $EntityManager->getRepository('Your\Entity')->find(1); // Retrieve the entity
$entity->setDate(new \DateTime('2000-01-01'));
$EntityManager->flush(); // Reflush

Update2

我发现在合并后实现更新的更干净的方法是重新合并实体,例如:

The cleaner way I found to achieve the update after the merge is re-merge the entity, e.g. :

$entity = new Entity();
$entity->setId(1);
// Set all fields that the merge is depending on
$EntityManager->merge($entity); // The real merge that retrieve (without commit) or create
$EntityManager->flush();

$entity->setDate(new \DateTime('2000-01-01'));
$entityManager->merge($entity); // Remerge the object with the changed field
$EntityManager->flush(); // Working re-flush

但是这不会改变主要问题,并没有真正做到感觉,因为你不能自己比较 DateTime 对象, $ entity-> getDate()在调用前总是返回null

But this doesn't change the main problem and doesn't really make sense because you cannot compare the DateTime object by yourself, $entity->getDate() return always null before calling setDate, even after the first merge.

通过引用(哈希)与<$ c $来比较对象, c $ c> setDate c> === ,即使对象日期未更改,新的 \DateTime 也会导致更新。

Doctrine compare the objects by reference (hash) with ===, also a new instance of \DateTime causes the update even if the object date is unchanged.

这是一个真正有问题的问题,可以通过使用 == 作为比较运算符来修复,但是教条不能做出具体的条件对于 \DateTime 而不会破坏其通用对象比较机制,这涉及到降低最常用功能之一的性能。

This is a really problematic issue that could be fixed by using == as comparison operator, but doctrine can't make a specific condition for \DateTime without breaking their generic object comparison mechanism, that involves to decrease performances of one of the most used feature.

这篇关于Doctrine merge:DateTime字段总是更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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