繁体   English   中英

在 Doctrine 中持久化实体时如何使用 DB 默认值?

[英]How to use DB default when persist entity in Doctrine?

我有实体 class 有很多像这样的字段:

/** @ORM\Entity() */
class Address
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    private int $id;

    /** @ORM\Column(type="datetime", name="add_time") */
    private DateTime $createdAt;

    /** @ORM\Column(type="text", name="full_address") */
    private string $fullAddress;

    /** @ORM\Column(type="string") */
    private string $street;

    // other fields
}

该实体有大约 20 个字段。 几乎所有这些都在数据库中定义为varchar(100) default '' not null

现在我要进行部分更新。 所以我只发送一个字段(或有时是字段的子集)而不是整个表单。 某些字段可能有一个空值(空字符串)。

据我了解,我不能使用$form->handleRequest来填充我的实体,所以我使用

$form->submit($request->request->all(), false);

但是在这种情况下,所有具有空字符串值的字段都没有设置到实体中。 并且 Doctrine 生成带有完整字段列表的 INSERT 语句,并将 null 值传递给占位符,这会导致Integrity constraint violation: 1048 Column 'street' cannot be null

我尝试了一些解决方案,但没有人为我工作:

  1. 设置字段默认值:
/** @ORM\Column(type="string") */
private string $street = '';

它产生Uncaught TypeError: Argument 1 passed to Entity\Address::setStreet() must be of the type string, null given$form->submit上给出。

  1. 在构造函数中设置默认值:
public function __construct()
{
    $this->street = '';
}

和第一个完全一样。

  1. 添加 Doctrine 默认选项:
/** @ORM\Column(type="string", options={"defalt": ""}) */
private string $street = '';

根本没有任何变化,因为BasicEntityPersister::getInsertColumnList不使用此信息。

  1. 第三次之后,我尝试实现自己的 EntityPersister,但看起来没有办法做到这一点。 Doctrine 不允许更改它。

我可能错过了一些非常简单和愚蠢的东西。

有没有办法从 INSERT 语句中排除具有默认值的字段?

当您从表单向实体提交数据时,具有空字符串值'' TextType 字段将转换为null并由setStreet()方法设置。 有关更多信息,请参阅文档https://symfony.com/doc/current/reference/forms/types/text.html#empty-data ,尤其是红框中的文本。 null 转换的空字符串值由TextType::reverseTransform方法执行。

有 2 个变体可以解决它:

1 - 修改二传手

public function setStreet(?string $street): self
{
    $this->street = (string) $street;

     return $this;
}

2 - 为表单构建器中的 TextType 添加自定义视图转换器或使用自定义视图转换器创建新表单类型

public function buildForm(FormBuilderInterface $builder, array $options)
{
    .....

    $builder->get('street')->addViewTransformer(new NullToEmptyStringTransformer());
}


class NullToEmptyStringTransformer implements DataTransformerInterface
{
    public function transform(mixed $value): mixed
    {
        return $value;
    }

    public function reverseTransform(mixed $value): string
    {
        return (string) $value;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM