У меня есть приложение Symfony 4, которое использует Doctrine для доступа ко всем базам данных. В рассматриваемой таблице есть ряд столбцов, которые определены с помощью «NOT NULL».
Все методы-получатели в классе сущности написаны так, что они возвращают пустую строку, если текущее значение равно нулю
public function getApartment(): string
{
return $this->apartment ?? '';
}
Насколько я понимаю, Doctrine вызывает методы получателя сущности для извлечения текущих значений при сохранении объекта в базе данных.
Я не вижу, как пишутся геттеры, подобные этому выше может привести к нулевым значениям, но иногда эта ошибка Обратите внимание, что это не происходит все время, только иногда, и я еще не заметил какого-либо паттерна.
В дополнение к получателям, некоторые определения полей сущности помечены аннотациями @Assert\NotBlank
, поэтому компонент Form не должен возвращать true из метода isValid()
.
Вот (слегка отредактированный) пример ошибки из var / log / prod.log:
[2020-03-02 22:23:22] request.CRITICAL: Uncaught PHP Exception
Doctrine\DBAL\Exception\NotNullConstraintViolationException:
"An exception occurred while executing
'INSERT INTO FreeClassQueries
(apartment, city, comment, dateCreated, email, migrated, name, phone, state, street, zip, spamInfo)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
with params [null, null, null, "2020-03-02 22:23:20", null, null, null, null, null, null, null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'apartment' cannot be null"
at /var/www/prod/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php line 103
{"exception":"[object] (Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException(code: 0):
An exception occurred while executing
'INSERT INTO FreeClassQueries
(apartment, city, comment, dateCreated, email, migrated, name, phone, state, street, zip, spamInfo)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
with params [null, null, null, \"2020-03-02 22:23:20\", null, null, null, null, null, null, null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048
Column 'apartment' cannot be null
at /var/www/prod/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:103,
Doctrine\\DBAL\\Driver\\PDOException(code: 23000): SQLSTATE[23000]:
Integrity constraint violation: 1048 Column 'apartment' cannot be null
at /var/www/prod/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:123,
PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1048
Column 'apartment' cannot be null at /var/www/prod/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:121)"} []
Как видите, единственное значение, которое не является нулевым, - это dateCreated. он устанавливается с помощью метода, помеченного аннотацией @ORM\PrePersist
.
Метод действия пытается сохранить объект только в том случае, если форма была отправлена и является действительной, то есть все поля, помеченные @Verify\NotBlank
не может быть пустым.
$form->handleRequest( $request );
if( $form->isSubmitted() && $form->isValid())
{
$em = $this->getEntityManager();
$repository = $em->getRepository( FreeClassQuery::class );
$em->persist( $classQuery );
$em->flush();
...
}