One-To-Many Relation in Symfony 2 with Doctrine

26,457

Solution 1

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.

Solution 2

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.

Share:
26,457
JonB
Author by

JonB

I am a Bristol based, freelance web developer. I build websites using Drupal or Zend Framework in an Agile way, and then test them using Selenium. I am Scrum Master Certified (CSM), which means I do a bit project management every now and again.

Updated on December 16, 2020

Comments

  • JonB
    JonB over 3 years

    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:

    • stripped back my entities so that they only have the minimum attributes and methods
    • have cleared the doctrine query cache / metadata cache
    • dropped and recreated the schema
    • checked my spelling

    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.