'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id_utilisateur_id' cannot be null

I am a computer science student. And I have a problem while creating an API.

Here is my controller allowing the addition of a "Personnage". (POST)

#[Route('/api/personnage', name: 'ajouterPersonnage', methods:['POST'])]
public function creePersonnage(Request $request, SerializerInterface $serializer, EntityManagerInterface $em, 
UtilisateurRepository $utilisateurRepository, VilleRepository $villeRepository, 
UrlGeneratorInterface $urlGeneratorInterface): JsonResponse
{
    $personnage = $serializer->deserialize($request->getContent(), Personnage::class, 'json');
    $em->persist($personnage);
    $em->flush();

    $content = $request->toArray();
    $idUtilisateur = $content['id_utilisateur_id'] ?? -1;
    $idVille = $content['id_ville_id'] ?? -1;


    $personnage->setIdUtilisateur($utilisateurRepository->find($idUtilisateur));
    $personnage->setIdVille($villeRepository->find($idVille));

    $jsonPersonnage = $serializer->serialize($personnage, 'json', ['groups' => 'get:info_personnage_full']);

    $location = $urlGeneratorInterface->generate('unPersonnage', ['id' => $personnage->getId()], UrlGeneratorInterface::ABSOLUTE_PATH);

    return new JsonResponse($jsonPersonnage, Response::HTTP_CREATED, ["Location" => $location], true);

}

and here is my "Personnage" entity :

#[ORM\Entity(repositoryClass: PersonnageRepository::class)]
class Personnage
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private $id;

    #[ORM\ManyToOne(targetEntity: Utilisateur::class, inversedBy: 'personnages')]
    #[ORM\JoinColumn(nullable: false)]
    #[Groups(['get:info_personnage_full'])]
    private $id_utilisateur;

    #[ORM\Column(type: 'string', length: 255)]
    #[Groups(['get:info_personnage_full'])]
    private $nom;

    #[ORM\Column(type: 'string', length: 255)]
    #[Groups(['get:info_personnage_full'])]
    private $prenom;

    #[ORM\OneToOne(mappedBy: 'id_personnage', targetEntity: SituationPersonnage::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $situationPersonnage;

    #[ORM\OneToOne(mappedBy: 'id_personnage', targetEntity: InteractionsPersonnage::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $interactionsPersonnage;

    #[ORM\OneToMany(mappedBy: 'id_personnage', targetEntity: DiplomesPersonnage::class)]
    #[Groups(['get:info_personnage_full'])]
    private $diplomesPersonnages;

    #[ORM\OneToOne(mappedBy: 'id_personnage', targetEntity: SantePersonnage::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $santePersonnage;

    #[ORM\ManyToOne(targetEntity: Ville::class, inversedBy: 'personnages')]
    #[Groups(['get:info_personnage_full'])]
    private $id_ville;

    #[ORM\OneToMany(mappedBy: 'id_createur', targetEntity: Entreprise::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $entreprises;

    #[ORM\OneToMany(mappedBy: 'id_personnage', targetEntity: CompteBancaire::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $compteBancaires;

    #[ORM\OneToMany(mappedBy: 'id_personnage', targetEntity: AddictionsPersonnage::class, cascade: ['persist', 'remove'])]
    #[Groups(['get:info_personnage_full'])]
    private $addictionsPersonnages;

When I try to insert a "Personnage", I get an error :

The error

I think he can't find the reference id_personnage_id... but nevertheless it exists : database table

Can you help me I've been totally stuck for several hours...



Solution 1:[1]

Your problem is you're trying to flush the Personnage with an invalid state. When you flush an entity with the Entity Manager, it actually saves the data in the database. Since your property $id_utilisateur is not nullable, it has to have a value before you save it to the database.

Your code should look something like this:

#[Route('/api/personnage', name: 'ajouterPersonnage', methods:['POST'])]
public function creePersonnage(Request $request, SerializerInterface $serializer, EntityManagerInterface $em, 
UtilisateurRepository $utilisateurRepository, VilleRepository $villeRepository, 
UrlGeneratorInterface $urlGeneratorInterface): JsonResponse
{
    $personnage = $serializer->deserialize($request->getContent(), Personnage::class, 'json');

    $content = $request->toArray();
    $idUtilisateur = $content['id_utilisateur_id'] ?? -1;
    $idVille = $content['id_ville_id'] ?? -1;

    $personnage->setIdUtilisateur($utilisateurRepository->find($idUtilisateur));
    $personnage->setIdVille($villeRepository->find($idVille));

    $em->persist($personnage);
    $em->flush();

    $jsonPersonnage = $serializer->serialize($personnage, 'json', ['groups' => 'get:info_personnage_full']);

    $location = $urlGeneratorInterface->generate('unPersonnage', ['id' => $personnage->getId()], UrlGeneratorInterface::ABSOLUTE_PATH);

    return new JsonResponse($jsonPersonnage, Response::HTTP_CREATED, ["Location" => $location], true);

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Julien B.