I have entity class with many fields like so:
/** @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
}
This entity has about 20 fields. Almost all of them are defined as varchar(100) default '' not null
in the database.
Now I'm going to do a partial update. So I send just a single field (or sometimes a subset of fields) instead of entire form. Some fields may have an empty value (empty string).
As I understand, I can not use $form->handleRequest
to populate my entity, so I use
$form->submit($request->request->all(), false);
But in this case all fields with empty string value are not set into the entity. And Doctrine generates INSERT statement with full list of fields and pass null values into placeholders, and that causes Integrity constraint violation: 1048 Column 'street' cannot be null
I tried some solutions, but no one worked for me:
/** @ORM\Column(type="string") */
private string $street = '';
It produces Uncaught TypeError: Argument 1 passed to Entity\Address::setStreet() must be of the type string, null given
on $form->submit
.
public function __construct()
{
$this->street = '';
}
Exactly the same as the 1st one.
/** @ORM\Column(type="string", options={"defalt": ""}) */
private string $street = '';
No changes at all because BasicEntityPersister::getInsertColumnList
doen't use this information.
I probbly missed something very symple and stupid.
Is there a way to exclude fields with default values from INSERT statement?
When you submit data from the form to the entity, TextType field with empty string value ''
is transformed to the null
and set by setStreet()
method. For more information see the documentation https://symfony.com/doc/current/reference/forms/types/text.html#empty-data , especially the text in the red box. Empty string value to the null transformation is executed by method TextType::reverseTransform
.
There are 2 variants to resolve it:
1 - modify setter
public function setStreet(?string $street): self
{
$this->street = (string) $street;
return $this;
}
2 - add a custom view transformer for the TextType fied in the form builder or create a new form type with custom view transformer
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.