Doctrine терпит неудачу с колонкой не может быть нулевой ошибкой; Не вижу, как значение _can_ может быть нулевым - PullRequest
1 голос
/ 04 марта 2020

У меня есть приложение 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();
  ...
}

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Вы предполагаете, что Doctrine будет использовать геттеры объекта, , но это не так . Начиная с Doctrine документов :

Doctrine НИКОГДА не затрагивает API методов publi c в ваших классах сущностей (таких как геттеры и сеттеры) или конструктор метод. Вместо этого он использует отражение, чтобы получить / установить данные от / к объектам вашей сущности. Когда Doctrine извлекает данные из БД и сохраняет их обратно, любой код, вставленный в ваши методы get / set, не будет неявно учтен.

Вместо помещения этого лога c в getter, просто создайте значение по умолчанию по умолчанию для свойств объекта. Это также поможет вам получить более чистый добытчик, не прибегая к хитростям:

class Foo
{
    private string $apartment = '';

    public function getApartment(): string
    {
        return $this->apartment;
    }
}
0 голосов
/ 05 марта 2020

У вас есть основная проблема c Php: ваша переменная рассматривается как 'ложная'. Переменная - это переменная , которая считается пустой, если она неопределена, имеет значение null, false, 0 или пустую строку .

Возможное решение: установить значение по умолчанию.

В любом случае, попробуйте, что лучше для вашего приложения, и позаботьтесь.

...