Doctrine 2 пр. c Symfony 4.2.5 et FOSRestBundle - Ассоциация OneToMany - Регистрация Redondant - PullRequest
0 голосов
/ 22 января 2020

Вот проблема:

Две сущности Книги и Авторы. У книги есть только один автор, у автора может быть несколько книг.

Когда база заполняется, если я создаю книгу с существующим автором в таблице Auteurs, она создает (ошибочно) дубликат в таблице .

Наличие аннотации cascade = "persist" является источником этого дубликата. Если я удаляю эту аннотацию, я получаю сообщение об ошибке:

{"error": {"code": 500, "message": "Internal Server Error", "exception": [{"message": "A новый объект был найден с помощью отношения 'App \ Entity \ Books # auteur' .....

Как решить этот вопрос? Мой код: Контроллер:

<?php

namespace App\Controller;

use App\Entity\Books;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

class EcritureController extends FOSRestController
{
    /**
     * @Rest\Post(
     *  path = "/creer-book")
     * @Rest\View(StatusCode = 201)
     * @ParamConverter("book", converter="fos_rest.request_body")
     */
    public function creerBook(Books $book)
    {
        $em->persist($book);
        $em->flush();
        return $book;
    }
}

Entity Books :

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\BooksRepository")
 */
class Books
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $titre;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Books", inversedBy="Books", cascade={"persist"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $auteur;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitre(): ?string
    {
        return $this->Titre;
    }

    public function setTitre(string $titre): self
    {
        $this->titre = $titre;

        return $this;
    }

    public function getAuteur(): ?Auteurs
    {
        return $this->auteur;
    }

    public function setAuteur(?Auteurs $auteur): self
    {
        $this->auteur = $auteur;

        return $this;
    }
}

Авторы сущностей:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\AuteursRepository")
 */
class Auteurs
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=10)
     */
    private $nom;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Books", mappedBy="auteur") 
     */
    private $books;

    public function __construct()
    {
        $this->books = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getNom(): ?string
    {
        return $this->nom;
    }

    public function setNom(string $nom): self
    {
        $this->nom = $nom;

        return $this;
    }

    /**
     * @return Collection|Books[]
     */
    public function getBooks(): Collection
    {
        return $this->books;
    }

    public function addBook(Books $book): self
    {
        if (!$this->books->contains($book)) {
            $this->books[] = $book;
            $book->setBook($this);
        }
        return $this;
    }

    public function removeBook(Books $book): self
    {
        if ($this->books->contains($book)) {
            $this->sujets->removeElement($book);
            // set the owning side to null (unless already changed)
            if ($book->getAuteur() === $this) {
                $book->setAuteur(null);
            }
        }
        return $this;
    }
}

1 Ответ

0 голосов
/ 23 января 2020

Ошибка заключалась в том, чтобы «сохранять» сторону «многих». Необходимо сохранить «Единую» сторону следующим образом:

        $auteurId = $book->getAuteur()->getId();
        $auteur= $em->getRepository('App:Auteurs')->find($auteurId);
        $response = new Response();
        if ($auteur) {
            $auteur->addBook($book);
            $em->persist($auteur);
            $em->flush();
            $response->setContent('Chain of your choice', Response::HTTP_OK);
        } else {
            $response->setContent('Auteur selected doesn\'t exist', Response::HTTP_NOT_ACCEPTABLE);
        }

        return $response;
...