symfony Doctrine在更新CURRENT_TIMESTAMP时不断更新DATETIME

deyfvvtc  于 2023-11-22  发布在  其他
关注(0)|答案(2)|浏览(169)

我有父实体类:

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的一些配置/注解吗?或者你必须以其他方式指定这个属性吗?

ix0qys7i

ix0qys7i1#

你可能在Lifecycle Callbacks之后。如果是这样,这是要走的路:

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

字符串

kyvafyod

kyvafyod2#

@Peyman Mohamadpour的回答可能提供了更符合PHP标准的方法,但是我想解决最初的问题-为什么会发生这种情况。
我能看出两个原因...

核心问题-columnDefinition

columnDefinition允许你定义不可移植的--因此也是非原则的--东西,因为原则在试图生成当前表模式的状态时不会生成它,它把它看作是一个变化,文档对此非常清楚:
columnDefinition:允许定义用于创建列的自定义XML代码段。警告:这通常会混淆SchemaTool始终检测到列已更改。

次要问题

您的实体列定义与DB中的定义不同-在数据库中,您的列是NULL,
在原则实体中**ORM\Column默认有nullable = false**
(be注意**ORM\JoinColumn不一样-默认情况下是nullable = true**!)
..由于这是一个旧的Q,我将故意展示现代属性方法:

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来定义已知类型

相关问题