Trying to update an entity, and submitting a field with a value that is unchanged results in a type error. What am I doing wrong?
Entity:
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
...
class User implements UserInterface
{
...
/**
* @ORM\Column(type="bigint", nullable=true)
* @Groups({"default", "listing"})
* @Assert\Type("integer")
*/
private $recordQuota;
...
FormType:
<?php
namespace App\Form;
...
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
...
->add('recordQuota', IntegerType::class)
;
}
...
}
Controller:
...
/**
* @Route("/api/user/{id}", name="editUser")
* @Method({"PUT", "PATCH"})
* @Rest\View()
*/
public function updateAction(Request $request, User $user)
{
$form = $this->createForm(UserType::class, $user);
$data = $request->request->get('user');
$clearMissing = $request->getMethod() != 'PATCH';
$form->submit($data, $clearMissing);
if ($form->isSubmitted() && $form->isValid()) {
...
I'm using PostMan to submit form data. If the entity I am updating has a recordQuota of 1000, and I submit the form with a different value. It all works and updates.
But if I submit my form with recordQuota: 1000, which should leave the value unchanged I get an incorrect type error:
"recordQuota": {
"errors": [
"This value should be of type integer."
]
}
Additional info:
I am using $form->submit
instead of handleRequest
because I am using patch. So I need to be able to enable/disable $clearMissing
. But even using handleRequest
creates the same issue.
Even typecasting the recordQuota as int before passing it to the form still fails.
If I remove all of the type information from the Form and the Entity, I get "This value should be of type string" when actually making a change.
This was an issue with a combination of Symfony 4.3 validator auto_mapping described here: https://symfony.com/blog/new-in-symfony-4-3-automatic-validation
And the maker bundle adding the wrong typecast to bigint fields.
See here: https://github.com/symfony/maker-bundle/issues/429
The answer was to change the getters and setters in the entity from:
public function getRecordQuota(): ?int
{
return $this->recordQuota;
}
public function setRecordQuota(?int $recordQuota): self
{
$this->recordQuota = $recordQuota;
return $this;
}
to
public function getRecordQuota(): ?string
{
return $this->recordQuota;
}
public function setRecordQuota(?string $recordQuota): self
{
$this->recordQuota = $recordQuota;
return $this;
}
Alternatively, one can turn off auto_mapping in the validator config.