You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doctrine EntityManager未插入ID列问题排查

Doctrine ORM持久化手动赋值UUID实体时ID字段无默认值问题解决

问题现象

采用六边形架构开发,使用Doctrine ORM管理数据实体,MealOptOut实体通过HasUuid trait定义ID字段,并在构造函数中手动生成UUID。调用EntityManager的persist()+flush()方法持久化时触发SQL错误:

An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1364 Field 'id' doesn't have a default value

日志显示Doctrine生成的INSERT语句未包含id列,但实体的ID已确认正确赋值,且同架构下其他实体可正常工作,目前只能通过手动执行SQL临时解决。

问题根源

Doctrine ORM对ID字段默认采用AUTO生成策略,它会默认认为ID由数据库自动生成(比如自增主键),因此在生成INSERT语句时会主动忽略ID字段,即便你已经手动为实体的ID赋值。而其他同架构实体可能已经正确配置了ID生成策略,所以未出现该问题。

解决方案

在HasUuid trait的ID字段上添加#[ORM\GeneratedValue(strategy: 'NONE')]注解,明确告知Doctrine该ID字段由业务代码手动生成,不需要ORM自动处理。

修改后的HasUuid trait代码:

<?php

namespace App\Domain\Model;

use Doctrine\ORM\Mapping as ORM;

trait HasUuid
{
    #[ORM\Id]
    #[ORM\Column(name: 'id', type: 'string', unique: true)]
    #[ORM\GeneratedValue(strategy: 'NONE')] // 新增该注解
    protected string $id;

    public function getId(): string
    {
        return $this->id;
    }

    public function setId(string $id): void
    {
        $this->id = $id;
    }
}

额外验证步骤

  1. 确认数据库表meal_opt_out的id字段未设置为自增类型(UUID为字符串类型,无需自增)
  2. 恢复Repository中原本的save方法:
public function save(MealOptOut $mealOptOut): void
{
    $this->getEntityManager()->persist($mealOptOut);
    $this->getEntityManager()->flush();
}
  1. 重新执行持久化操作,检查Doctrine生成的INSERT语句是否已包含id列,确认错误消失。

内容的提问来源于stack exchange,提问作者O'Niel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:04:51