Search code examples
symfonydoctrine-ormdoctrinesymfony-2.1dql

Why do I get empty objects in my collection Many-to-Many


I am getting empty objects in my collection. I have a manytomany relationship and updated my schema..

I have 2 entities;

  • Vacancy
  • Meetup

A vacancy can have more than 1 Meetup.

My Vacancy entity;

/**
 * @var Collection
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Meetup", inversedBy="vacancies", cascade={"persist"}, indexBy="id", fetch="EAGER")
 */
private $meetups;

Constructor of Vacancy entity;

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

Getters and setters;

/**
 * @return Collection
 */
public function getMeetups()
{
    return $this->meetups;
}

/**
 * @param Meetup $meetup
 */
public function addMeetup(Meetup $meetup)
{
    $this->meetups->add($meetup);
}

/**
 * @param Meetup $meetup
 */
public function removeMeetup(Meetup $meetup)
{
    $this->meetups->removeElement($meetup);
}

My Meetup entity;

/**
 * @var Collection
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Vacancy", inversedBy="meetups", cascade={"persist"})
 */
private $vacancies;

In my repository I am doing such thing as;

$qb = $this->createQueryBuilder('group');
$qb->innerJoin('group.vacancies', 'vacancy');
$qb->innerJoin('vacancy.meetups', 'm');

And my result looks like;

"meetups": [
        {},
        {},
        {}
      ],

Whats wrong with this relation? I have 3 records and I get 3 empty objects. Any help will be appreciated!

EDIT: My serialization file looks like; (this is my Vacancy serialization file)

clubhouseMeetups: expose: true groups: [app,vacancies]


Solution

  • 1/ Your ManyToMany relationship isn't correct. When you have a bidirectional ManyToMany you should have one inversedBy and one mappedByon the other side (cf http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#many-to-many-bidirectional).

    /**
     * @var Collection
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Vacancy", mappedBy="meetups", cascade={"persist"})
     */
    private $vacancies;
    

    2/ If you try to use your Meetup entity in order to add Vacancy your same getters and setters will not work because you will need to add the objects in both directions

    /**
     * @param Vacancy $vacancy
     */
    public function addVacancy(Vacancy $vacancy)
    {
        $vacancy->addMeetup($this);
        $this->vacancies->add($vacancy);
    }
    

    This is not required for inversedBy and if you do the same code you will have a infinite loop. The best solution (I think) is to only use one entry point for this relationship, use inversedByon it, also add the object in the other side and never use the other side.