API Platform v3.2.7中Gedmo Timestampable实体功能失效问题
问题复盘
在全新安装的API Platform 3.2.7中,为Greeting实体实现Gedmo Timestampable功能时,无论是用属性配置还是Trait方式,均触发SQL非空约束错误:SQLSTATE[23000]: 完整性约束违规: 1048 Column 'created_at' cannot be null;手动配置监听器时又遇到annotation_reader服务不存在的报错,该问题与Symfony 6.3中Doctrine生命周期订阅者的版本变更直接相关。
解决方案
1. 安装StofDoctrineExtensionsBundle(推荐方案)
手动配置Gedmo监听器易受Symfony版本变更影响,使用官方维护的StofBundle可自动适配版本差异,大幅简化配置流程:
composer require stof/doctrine-extensions-bundle
2. 启用Timestampable扩展
在config/packages/stof_doctrine_extensions.yaml中添加配置,开启Timestampable功能:
stof_doctrine_extensions: default_locale: en_US orm: default: timestampable: true
3. 实体配置(二选一)
方式一:PHP 8属性直接配置
用Gedmo属性注解标记时间字段,同时初始化字段避免IDE警告:
namespace App\Entity; use Gedmo\Mapping\Annotation as Gedmo; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Greeting { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private ?int $id = null; #[ORM\Column(type: 'string', length: 255)] private ?string $message = null; #[ORM\Column(type: 'datetime_immutable')] #[Gedmo\Timestampable(on: 'create')] private \DateTimeImmutable $createdAt; #[ORM\Column(type: 'datetime_immutable')] #[Gedmo\Timestampable(on: 'update')] private \DateTimeImmutable $updatedAt; public function __construct() { // 初始化字段避免IDE警告,Gedmo会自动覆盖为正确时间 $this->createdAt = new \DateTimeImmutable(); $this->updatedAt = new \DateTimeImmutable(); } // 省略getter/setter方法 }
方式二:使用Timestampable Trait
直接引入Gedmo提供的Trait,减少重复代码:
namespace App\Entity; use Gedmo\Timestampable\Traits\TimestampableEntity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] class Greeting { use TimestampableEntity; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private ?int $id = null; #[ORM\Column(type: 'string', length: 255)] private ?string $message = null; // 省略getter/setter方法 }
4. 验证Doctrine映射配置
确保config/packages/doctrine.yaml中ORM映射类型与实体配置匹配(属性/注解二选一):
doctrine: orm: mappings: App: type: attribute # 若使用旧注解则改为annotation dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' alias: App
5. 生成并执行数据库迁移
确保数据库表中created_at和updated_at字段正确生成:
php bin/console make:migration php bin/console doctrine:migrations:migrate
手动配置报错原因说明
Symfony 6.3中annotation_reader服务已被弃用,替换为doctrine.annotation_reader,但即使修改服务名,手动配置监听器仍需处理属性映射兼容、事件订阅优先级等细节,使用StofBundle可自动处理这些问题,彻底规避版本适配的麻烦。
内容的提问来源于stack exchange,提问作者Matías Cánepa

