JonB
JonB

Reputation: 1320

One-To-Many Relation in Symfony 2 with Doctrine

I've looked at literally tons of questions/answers on Stack Overflow and other places on the web, but cannot find a resolution to this problem.

Before I explain the problem, I have:

I have the following two entities:

<?php
namespace Docker\ApiBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

  /**
   * @ORM\Column(type="integer")
   * @ORM\ManyToOne(targetEntity="Project",inversedBy="sources")
   * @ORM\JoinColumn(referencedColumnName="id")
   */
  private $project;

}


<?php
namespace Docker\ApiBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

  /**
   * @ORM\OneToMany(targetEntity="Source", mappedBy="project")
   */
  private $sources;

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

  public function getSources() {
    return $this->sources;
  }
}

So a many 'sources' can belong to one 'project'.

In my controller I have:

$em = $this->getDoctrine()->getManager();
$project = $em->find('Docker\ApiBundle\Entity\Project', 1);
$sources = $project->getSources()->toArray();

I have tried lots of things but I always get:

Notice: Undefined index: project in /.../www/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1577

Like I say, I know there are a lot of questions going around about this, but none of the accepted answers fix my problem.

This all looks pretty fundamental to using Doctrine2 so not sure what I am doing wrong - it could be something really obvious.

Any help would be appreciated.

Upvotes: 3

Views: 26531

Answers (2)

gerda
gerda

Reputation: 73

If this is exactly your code, i dont see a namespace in your Project class. Try adding the namespace line "namespace Docker\ApiBundle\Entity;". If this is the same folder no need for "use" but if it s part of other bundle or folder try putting a line like "use Docker\ApiBundle\Entity\Project;" in your Source class. I Hope it helps..

Otherwise :

<?php
namespace Azimut\ApiBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

  private $name;


  /**
   * @ORM\Column(type="integer")
   * @ORM\ManyToOne(targetEntity="Azimut\ApiBundle\Entity\Project", inversedBy="sources")
   * @ORM\JoinColumn(onDelete="CASCADE")
   */
  private $project;


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set project
 *
 * @param integer $project
 * @return Source
 */
public function setProject($project)
{
    $this->project = $project;

    return $this;
}

/**
 * Get project
 *
 * @return integer 
 */
public function getProject()
{
    return $this->project;
}
}


<?php
namespace Azimut\ApiBundle\Entity;

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

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

  /**
   * @ORM\OneToMany(targetEntity="Azimut\ApiBundle\Entity\Source", mappedBy="object", cascade={"all"})
   */
  private $sources;

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

  public function getSources() {
    return $this->sources;
  }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

/**
 * Add sources
 *
 * @param \Azimut\ApiBundle\Entity\Source $sources
 * @return Project
 */
public function addSource(\Azimut\ApiBundle\Entity\Source $sources)
{
    $this->sources[] = $sources;

    return $this;
}

/**
 * Remove sources
 *
 * @param \Azimut\ApiBundle\Entity\Source $sources
 */
public function removeSource(\Azimut\ApiBundle\Entity\Source $sources)
{
    $this->sources->removeElement($sources);
}
}

and little part of the controller: public function helloAction()

{
        $id = 1;
        $em = $this->getDoctrine()->getManager();
        $project = $em->getRepository('Azimut\ApiBundle\Entity\Project')->find($id);

        $source1 = $em->getRepository('Azimut\ApiBundle\Entity\Source')->find(3);
        $source2 = $em->getRepository('Azimut\ApiBundle\Entity\Source')->find(5);
        $project->addSource($source1);
        $sources = array();
        $sources = $project->getSources();
        var_dump($sources);
        return ....
}

and this works just fine for me.

Upvotes: 1

Zeljko
Zeljko

Reputation: 5158

You have:

/**
* @ORM\Column(type="integer")
* @ORM\ManyToOne(targetEntity="Project",inversedBy="sources")
* @ORM\JoinColumn(referencedColumnName="id")
*/
private $project;

Remove:

@ORM\Column(type="integer")

from annotation.

Upvotes: 5

Related Questions