Symfony2 Много к одному - один ко многим без таблицы соединений

У меня есть объект "Проект", который может иметь несколько преимуществ, в то время как выгода принадлежит только одному проекту: мне кажется, что отношения один ко многим - один ко многим. Я следовал указаниям здесь

Объект проекта:

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\ProjectRepository")
 * @ORM\Table(name="projects")
 */
class Project
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\oneToMany(targetEntity="Benefit", mappedBy="project")
     */
    protected $benefits;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->benefits = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // other stuff

    /**
     * Add benefits
     *
     * @param \AppBundle\Entity\Benefit $benefits
     * @return Project
     */
    public function addBenefit(\AppBundle\Entity\Benefit $benefits)
    {
        $this->benefits[] = $benefits;

        return $this;
    }

    /**
     * Remove benefits
     *
     * @param \AppBundle\Entity\Benefit $benefits
     */
    public function removeBenefit(\AppBundle\Entity\Benefit $benefits)
    {
        $this->benefits->removeElement($benefits);
    }

    /**
     * Get benefits
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getBenefits()
    {
        return $this->benefits;
    }
}

Выгода является:

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitRepository")
 * @ORM\Table(name="benefits")
 */
class Benefit
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    // Other relevant fields

    /**
     * @ORM\ManyToOne(targetEntity="Project", inversedBy="benefits")
     */
    protected $project;

В моем контроллере я надеялся сделать:

$project = $em->getRepository('AppBundle:Project')->findOneById(3);

$benefit = new Benefit();
// set some fields for the new Benefit
$benefit->setProject($project);
$em->persist($benefit);

и я надеялся увидеть преимущества как совокупность внутри объекта проекта:

$benefits = $project->getBenefits();

Но это не сработало, поэтому я явно сделал:

$project->addBenefit($benefit);
$em->persist($project);
$benefits = $project->getBenefits();

И я действительно вижу новый недавно созданный Бенефит внутри проекта коллекции внутри. Проблема в том, что, если я повторно запишу это и добавлю новое преимущество к тому же проекту, я просто получу последнее. Конечно, если в одной и той же части кода я создаю 2 преимущества и добавляю оба, у меня есть набор из 2, но это не то, что я хочу. Со стороны Преимущества все в порядке: каждое новое Преимущество сохраняется, и все они правильно указывают на один и тот же Проект.

Что мне не хватает?

РЕДАКТИРОВАТЬ:

Вот шаги, которые я делаю / вещи, которые я проверял:

БД синхронизируется с метаданными текущего объекта. Обновленная сущность проекта:

<?php
// src/AppBundle/Entity/Project.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\ProjectRepository")
 * @ORM\Table(name="projects")
 */
class Project
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\oneToMany(targetEntity="Benefit", mappedBy="project", cascade="persist")
     */
    protected $benefits;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->benefits = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // Other irrelevant fields

    /**
     * Add benefits
     *
     * @param \AppBundle\Entity\Benefit $benefit
     * @return Project
     */
    public function addBenefit(\AppBundle\Entity\Benefit $benefit)
    {
        $this->benefits[] = $benefit;
        $benefit->setProject($this);
        return $this;
    }

    /**
     * Remove benefits
     *
     * @param \AppBundle\Entity\Benefit $benefits
     */
    public function removeBenefit(\AppBundle\Entity\Benefit $benefits)
    {
        $this->benefits->removeElement($benefits);
    }

    /**
     * Get benefits
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getBenefits()
    {
        return $this->benefits;
    }
}

Обратите внимание, что remove Benefit, вероятно, не реализован должным образом, но на данный момент это не актуально.

Я чищу таблицу преимуществ.

Я создаю новое преимущество и прикрепляю к проекту:

$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('AppBundle:Project')->findOneById(3);
$benefit = new Benefit();
$benefit->setName('Name of the benefit');
// here I set other irrelevant fields 
$project->addBenefit($benefit);

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

Преимущество должным образом сохраняется в БД. Это правильно ссылки на проект:

Затем я комментирую весь код в контроллере и просто выполняю:

$em = $this->getDoctrine()->getManager(); 
$project = $em->getRepository('AppBundle:Project')->findOneById(3);
$benefits = $project->getBenefits();
return $this->render('testBenefits.html.twig', array(
        'benefits' => $benefits, 'project' => $project));

Если я сбрасываю $project, я получаю:

И, конечно, если я сбрасываю $ выгоды, я получаю это:

1 ответ

Вы не устанавливаете проект в своем классе выгоды.

public function addBenefit(\AppBundle\Entity\Benefit $benefit)
{
    $this->benefits[] = $benefit;
    $benefit->setProject($this);  // Add this
    return $this;
}

Заметил, что я также изменил ваш аргумент от преимуществ к выгоде, так как addBenefit работает с одним объектом выгоды за раз.

Другие вопросы по тегам