symfonydoctrine-ormone-to-many

Doctrine2 OneToMany - ManyToOne returns empty collection with database ok



I have many relations of this type, but I can't see why this one is not working.
I have a Delegation and a Promotion entities:
Delegation

Promotion

    /**
 * Company\CBundle\Entity\Promotion
 * 
 * @ORM\Entity
 * @DoctrineAssert\UniqueEntity("promotionCode")
 */
class Promotion
{
    const REGISTER_DAYS = 30;
    const REGISTER_DISCOUNT = 100;

    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(name="promotionCode", type="string", unique=true, nullable=true)
     */
    protected $promotionCode;

    /**
     * @ORM\Column(name="name", type="string")
     */
    protected $name;

    /**
     * @ORM\Column(name="description", type="string", nullable=true)
     */
    protected $description;

    /**
     * @ORM\Column(name="days", type="integer")
     */
    protected $days;

    /**
     * @ORM\Column(name="discount", type="float")
     */
    protected $discount;

    /**
     * @ORM\ManyToOne(targetEntity="Delegation", inversedBy="promotions")
     * @ORM\JoinColumn(name="delegation_id", referencedColumnName="id")
     */
    private $delegation;

    /**
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="promotions")
     */
    private $product;

    /**
     * @var date $adquiredDate
     *
     * @ORM\Column(name="adquiredDate", type="date", nullable=true)
     */
    private $adquiredDate;

When in a controller I create a promotion, the table Promotion has the new object related to the delegation one

private function createPromotion($delegation)
{
    $em = $this->getDoctrine()->getEntityManager();
    $promotion = Promotion::createPromotion($delegacion, Promotion::REGISTER_DAYS, Promotion::REGISTER_DISCOUNT);
    $em->persist($promotion);
    $em->persist($delegation);

    $em->flush();
}

Database

*************************** 15. row ***************************
           id: 32
delegation_id: 19
         days: 20
     discount: 50
 adquiredDate: 2013-01-10

*************************** 16. row ***************************
           id: 33
delegation_id: 19
         days: 25
     discount: 50
 adquiredDate: 2013-01-10
*************************** 17. row ***************************
           id: 34
delegation_id: 19
         days: 30
     discount: 50
 adquiredDate: 2013-01-10

But when I call the $delegation->getPromotions() in another controller/action there is no promotions, returns a Doctrine\ORM\PersistentCollection with no data.

Can anyone help, please?


Edit with more information. $delegation->getPromotions() is empty, but looking for a promotion of that delegation and calling $promotion->getDelegation() is returning the delegation correctly :?


Solution

  • Have you tried defining your $delegation property like

    /**
     * @ORM\ManyToOne(targetEntity="Delegation", inversedBy="promotions")
     * @ORM\JoinColumn(name="delegation_id", referencedColumnName="id")
     */
    private $delegation;
    

    See Doctrine2 Docs: Association Mapping->Many-To-One


    Also there are a lot of typos in your code. For example

    /**
     * @ORM\OneToMany(targetEntity="Promotion", mappedBy="delegacion", cascade={"all"}, orphanRemoval=true)
     */
    protected $promotions;
    

    mappedBy="delegacion" should be mappedBy="delegation".

    Or

    public function getDeleTacion()
    {
        return $this->deleTacion;
    }
    

    Should be

    public function getDelegation()
    {
        return $this->delegation;
    }
    

    Edit

    Okay, I created a minimalistic version for you that worked for me. You can built it up from there or watch for differences with your code:

    Promotion.php

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     */
    class Promotion
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @ORM\ManyToOne(targetEntity="Delegation", inversedBy="promotions", cascade={"persist"})
         * @ORM\JoinColumn(name="delegation_id", referencedColumnName="id")
         */
        public $delegation;
    
        /**
         * @ORM\ManyToOne(targetEntity="Product", inversedBy="promotions", cascade={"persist"})
         * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
         */
        public $product;
    }
    

    Delegation.php

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     */
    class Delegation
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @ORM\OneToMany(targetEntity="Promotion", mappedBy="delegation", cascade={"all"}, orphanRemoval=true)
         */
        public $promotions;
    
        public function __construct() {
            $this->promotions = new \Doctrine\Common\Collections\ArrayCollection();
        }
    }
    

    Product.php

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     */
    class Product
    {
        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
    
        /**
         * @ORM\OneToMany(targetEntity="Promotion", mappedBy="product", cascade={"all"}, orphanRemoval=true)
         */
        public $promotions;
    
        public function __construct() {
            $this->promotions = new \Doctrine\Common\Collections\ArrayCollection();
        }
    }
    

    If you now do something like

    $delegation = new Delegation();
    $product = new Product();
    $promotion = new Promotion();
    $promotion->delegation = $delegation;
    $promotion->product = $product;
    
    $em->persist($promotion);
    $em->flush();
    
    $products = $em->createQuery('select p from BundleName\Entity\Product p')->execute();
    $delegations = $em->createQuery('select d from BundleName\Entity\Delegation d')->execute();
    
    var_dump(count($products[0]->promotions), count($delegations[0]->promotions));
    

    You should end up with

    int(1)
    int(1)
    

    So the refrence is in fact saved and can be read. Phew. Good luck with that! :-)