我有父实体类:
namespace App\Model\Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class ParentEntity
{
/**
* @var int|null
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="datetime", columnDefinition="DATETIME on update CURRENT_TIMESTAMP")
*/
protected $modifiedOn;
}
每次我运行
php bin/console o:s:u --dump-sql
或 --force
时,控制台都会打印出将执行 X 个查询,并且每个查询都针对 modified_on
列。
ALTER TABLE contact CHANGE modified_on modified_on DATETIME on update CURRENT_TIMESTAMP;
ALTER TABLE about_us CHANGE modified_on modified_on DATETIME on update CURRENT_TIMESTAMP;
ALTER TABLE image CHANGE modified_on modified_on DATETIME on update CURRENT_TIMESTAMP;
...
在 MySQL 数据库中,一切都设置正确:
CREATE TABLE `about_us` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`modified_on` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
所以我的问题是为什么会发生这种情况?我是否错过了 Doctrine 的某些配置/注释?或者您是否必须以其他方式指定此属性?
您可能正在寻找生命周期回调。如果是这样,这就是要走的路:
namespace App\Model\Entities;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
* @ORM\HasLifecycleCallbacks
*/
abstract class ParentEntity
{
/**
* @var int|null
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="datetime")
*/
protected $modifiedOn;
/**
* @ORM\PreUpdate
*/
public function setModifiedOn()
{
$this->modifiedOn = new \DateTime();
}
}
@Peyman Mohamadpour 的答案可能提供了更符合 php 标准的方法,但是我想解决最初的问题 - 为什么会发生这种情况。
我可以立即看到两个原因......
columnDefinition
columnDefinition 允许您定义不可移植的 - 因此是非教义的 - 事物,并且由于在尝试生成当前表模式的状态时教义不会生成它,因此它将其视为更改,并且 文档对此非常清楚 :
:允许定义用于创建列的自定义 DDL 片段。警告:这通常会导致 SchemaTool 混淆,使其始终检测到已更改的列。columnDefinition
您的实体列定义与数据库中的定义不同 - 在数据库中您的列可以为空,
在学说实体
ORM\Column
中默认有 nullable = false
ORM\JoinColumn
并不相同 - 默认情况下是 nullable = true
!)
nullable=true
并让属性可以为 null,并将 null 作为默认值 - 因为这是一个旧问题,我将有意展示现代属性方法:
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
...
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true]
private ?\DateTimeImmutable $modifiedOn = null;
#[ORM\PreUpdate]
public function setModifiedOn(): void
{
$this->modifiedOn = new \DateTimeImmutable();
}
您可能还需要在类上定义
#[ORM\HasLifecycleCallbacks]
,但我对此并不确定 - 它可能在很大程度上取决于 Doctrine 版本,因为我见过一些未定义但有效的情况,但也见过一些情况它已被定义并且仍处于最新稳定状态...
尽可能避免
columnDefinition
对于这些情况使用生命周期回调(也在 Symfony 中记录)
\DateTimeImmutable
,并且不要忘记告诉你正在使用的学说
使用
Doctrine\DBAL\Types\Types
定义学说已知类型