TYPO3 Extbase:在控制器操作中更新记录时,值为 NULL 的域模型 属性 未转换为零

TYPO3 Extbase: Domain model property with value NULL is not converted to zero when updating record in controller action

我遇到了以下问题:

#1470230767 TYPO3\CMS\Extbase\Persistence\Generic\Storage\Exception\SqlErrorException
Column 'linked_module' cannot be null

我有一个领域模型 属性:

/**
 * @var Module|null
 */
protected ?Module $linkedModule = null;

模块只是另一个领域模型,这个值不是强制性的。数据库定义如下所示:

linked_module   int(11) unsigned DEFAULT '0' NOT NULL,

最后但并非最不重要的相关 TCA:

config => [
    'autoSizeMax' => 1,
    'default' => 0,
    'eval' => 'int',
    'foreign_table' => 'tx_psbriskassessment_domain_model_module',
    'items' => [
        ['---', 0],
    ],
    'maxitems' => 1,
    'minitems' => 0,
    'renderType' => 'selectSingle',
    'size' => 1,
    'type' => 'select',
]

在我的控制器的一个动作中,我想重置这个属性的值:

$module->setLinkedModule(null);
$this->moduleRepository->update($module);

这会引发异常(请参阅此 post 的开头)。 我正在使用 TYPO3 v11.5.4 并假设 DataMapper 会因为 eval=int 而将 NULL 转换为 0。但这并没有发生。

我深入核心并到达了 EXT:extbase/Classes/Persistence/Generic/Backend.php 中的函数 persistObject()(第 295 行)。如果我正确阅读了代码,NULL 值总是作为 NULL 传递给数据库 - 此时无法进行转换。

我敢肯定,我只是遗漏了一个简单的观点。在数据库服务器上禁用严格模式对我来说不是一个选择。必须有一个干净的解决方案。

null 与 0 不同。该关系可能与 UID 为 0 的记录相关(这是不寻常的,但并未被设计禁止或阻止)。

因此,将未设置的关系 ($linkedModule = null) 自动转换为整数 0 会伪造信息。

最简单和最干净的方法应该是定义与您的模型匹配的数据库:没有默认值 0,而是可以为 null。

linked_module   int(11) unsigned,