mysqltypo3extbasetypo3-11.x

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


I'm stuck with the following problem:

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

I've got a domain model with this property:

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

Module is just another domain model and this value is not mandatory. The database definition looks like this:

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

and last but not least the relevant 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',
]

In an action of my controller I want to reset the value of this property:

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

This raises the exception (see beginning of this post). I'm using TYPO3 v11.5.4 and assumed that the DataMapper would convert NULL to 0 because of the eval=int. But that does not happen.

I dived into the core and reached the function persistObject() in EXT:extbase/Classes/Persistence/Generic/Backend.php (line 295). If I read the code correctly, a NULL-value is always passed as NULL to the database - no conversion possible at this point.

I'm sure, I'm just missing a simple point. Disabling strict mode on the database server is no option for me. There has to be a clean solution.


Solution

  • null is different from 0. The relation could be to a record with UID 0 (which is unusual but not forbidden or prevented by design).

    So, automatic conversion of a not-set relation ($linkedModule = null) to an integer 0 would falsify the information.

    The simplest and cleanest way should be to define the database matching your model: without default value 0, but instead nullable.

    linked_module   int(11) unsigned,