Bonjour,

J'ai une relation oneToMany entre une entité "Advert" et une entité "Photo" :

Dans mon entité "Avert" :

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Photo", mappedBy="advert", cascade={"persist"}, orphanRemoval=true)
     */
    private $photos;

Dans mon entité "Photo" :

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Advert", inversedBy="photos")
     * @ORM\JoinColumn(name="id", referencedColumnName="id")
     */
    private $advert;

Lorsque je persiste mon entité "Avert" à laquelle sont liées plusieurs photos

            $manager->persist($advert);
            $manager->flush();

j'obtiens une erreur de violation de contrainte de la clé primaire de mon entité "Photo" :

"An exception occurred while executing 'INSERT INTO photo (name, extension, id) VALUES (?, ?, ?)' with params ["tripick-triple-8-13l.jpg", "jpeg", 5]:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '5' for key 'PRIMARY'"

J'ai vu sur le net que ce problème a plusieurs fois été abordé, mais je ne parviens pas à trouver la solution.

Quelqu'un aurait une idée?

Merci d'avance pour votre aide.

12 réponses


dubitoph
Auteur
Réponse acceptée

J'ai résolu le problème en bouclant dans mes photos et en leur assignant l'annonce.

Bonjour,

L'erreur est pourtant assez claire, "Integrity constraint violation: 1062 Duplicate entry '5' for key 'PRIMARY'".
Tu essaies d'insérer ton $advert avec 5 comme id sauf que il y a déjà un $advert avec 5 comme id.

Ton id étant ta clé primaire celle-ci ne peut pas être dupliqué.

Comment as-tu attribué l'id de ton advert ?

dubitoph
Auteur

Merci beaucoup pour ton intérêt.

J'avais préalablement vidé les tables, donc il n'y subsistait aucun enregistrement.

Concernant la création des id, voici la déclaration dans chacune des entités concernées :

Dans "Advert" :

     /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;

Dans "Photo :

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;

Donc, selon moi, mes id devraient automatiquement être incrémentés.

C'est vraiment étrange du coup, essaye d'afficher ce qu'il y a dans ta base avant de faire le persist pour vérifier qu'il n'y ait bien aucune entré dans ta base.

Et affiche les photos parce que c'est apparement ça qui pose problème.
INSERT INTO photo
Pour moi une photo avec l'id 5 doit déjà exister.

dubitoph
Auteur

Etant donné que j'ai fais des delete et non un tuncate, l'auto-incrément recommence au dernier id connu, même si l'enregistrement n'existe plus.

Qu'entends-tu par afficher ce qu'il y a dans ma base de données ainsi que les photos?

Mes tables "advert" et "photo" sont bien vides. J'ai fait des captures d'écran pour te le monter, mais je ne sais pas comment lier des images à un post de ce forum.

dubitoph
Auteur

MySQL a retourné un résultat vide (c'est à dire aucune ligne). (traitement en 0,0000 seconde(s).)
SELECT * FROM photo
Profilage [Éditer en ligne] [ Éditer ] [ Expliquer SQL ] [ Créer le code source PHP ] [ Actualiser]

id name extension

MySQL a retourné un résultat vide (c'est à dire aucune ligne). (traitement en 0,0000 seconde(s).)
SELECT * FROM advert
Profilage [Éditer en ligne] [ Éditer ] [ Expliquer SQL ] [ Créer le code source PHP ] [ Actualiser]

id vehicle_id description created_at updated_at expires_at

Je parlais de faire une requête de type

dump($this->getDoctrine()->getRepository(Advert::class)->findAll());
et
dump($this->getDoctrine()->getRepository(Photo::class)->findAll());

dans ton controller pour vérifier qu'il ne te renvoie bien aucune réponse.

Si les dumps sont vides => [] alors franchement je ne comprends pas ...

dubitoph
Auteur

Voici ce que donnent les 2 var_dump() :

C:\cmder\roadtrip\src\Controller\RoadTripController.php:287:
array (size=0)
empty
C:\cmder\roadtrip\src\Controller\RoadTripController.php:287:
array (size=0)
empty

Peux-tu me montrer le code de ton controller en entier stp ?

dubitoph
Auteur

Voici le code de la fonction qui appelle le formulaire et qui enregistre celui-ci :

    /**
     *  @Route("/road_trip/newAdvert", name="road_trip_createAdvert")
     *  @Route("/road_trip/{id}/editAdvert", name="road_trip_editAdvert")
     */

    public function advertForm(Advert $advert = null, Request $request, ObjectManager $manager){

        if (!$advert) {
            $advert = new Advert();
            $vehicle = new Vehicle();
            $advert->setVehicle($vehicle);

            $photo1 = new Photo();
            $photo2 = new Photo();            
            $advert->addPhoto($photo1);
            $advert->addPhoto($photo2);

            $vehicle->setAdvert($advert);
        }
        /*else {

            $originalPhotos = new ArrayCollection ();

            // Create an ArrayCollection of the current Tag objects in the database
            foreach ($advert->getPhotos() as $photo ) {
                $originalPhotos->add($photo);
            }
        }*/

        $form = $this->createForm(AdvertType::class, $advert);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            //If it's a new advert, date assignment and expiration date assignement
            $now = new \DateTime();

            $advert->setCreatedAt($now);
            $advert->SetExpiresAt($now->add(new DateInterval('P1Y')));

            $photos = $advert->getPhotos();

            $manager->persist($advert);
            $manager->flush();

        }

        return $this->render('road_trip/createAdvert.html.twig', ['formAdvert' => $form->createView(), 'editMode' => $advert->getId() !== null]);        
    }

Bonjour.
Pour commencer, si le champ id de la table photo est en auto-increment, comment se fait-il que dans la requête SQL il y ait une valeur pour ce champ de défini ?
D'ailleurs, ce que je ne comprends pas, c'est que dans le code que tu nous montre, tu crées deux entités Photo vides pour une nouvelle entité Advert, je ne vois aucun sens à ceci.

dubitoph
Auteur

Je ne sais pas... Ce n'est pas le comportement normal?

Concernant les deux entités Photo, je les crée en fonction d'un tutoriel que j'ai lu et qui permet d'ajouter ou de supprimer des images "à la volée" via du javascript. En fait, ça n'a, selon moi, pas beaucoup d'importance ... mais je me trompe peut-être :)