Doctrine:如何手动设置实体的MySQL时间戳

时间:2016-06-07 16:18:19

标签: php mysql doctrine-orm

我想更新实体,但也保留其现有的时间戳。换句话说,在大多数情况下,我希望这个MySQL时间戳自动执行它的设计,但在某些情况下我想作弊 - 潜入更新而不更改此最后修改列。当然,使用SQL手动执行此操作是件小事,当然:

UPDATE events SET admin_notes = "foo", lastmod = lastmod WHERE /*...*/

但我无法想象如何让Doctrine这样做。

该实体名为Application\Entity\Event,列/注释如下:

/**
 *  @ORM\Column(name="lastmod",type="datetime") 
 *  @var \DateTime
 */
protected $modified;

基础表定义,相关部分:

lastmod timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

所以,我得到一个Event并尝试,例如,

$timestamp = $event->getModified();
echo "existing timestamp is: ".$timestamp->format('Y-m-d H:i:s')."\n";
//2016-06-07 10:13:15

$event
    ->setAdminNotes("this is an update at ".date('Y-m-d H:i:s'))
    ->setModified($timestamp);
$em->flush();

这不起作用。内存中实体对象中的时间戳是“正确的”,即未更改,但在实际数据库中,它被设置为当前日期时间,就好像它没有听到我说的那样。当然,查看SQL日志就是这样。我的$event->setModified($timestamp)没有进入生成的SQL语句。

是的,我意识到我可以将表的数据类型更改为MySQL日期时间并在整个应用程序中手动处理它。现在不是一个选择。

为了论证,我尝试从实体管理器获取Doctrine\DBAL\Connection,并自己运行executeUpdate($SQL),并发现(从SQL日志中)如果我在flush()之前执行此操作,它被忽略了。所以现在,唯一有效的方法是非常难看:将旧时间戳保留在变量中,执行flush(),然后运行另一个UPDATE以手动将其设置回原来的状态。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

Doctrine看到你没有修改你的$ timestamp对象,这就是为什么它不包含在sql查询中。试着

$newTimestamp = clone $timestamp; 
$event->setModified($newTimestamp);