Skip to content
Create a gist now

Instantly share code, notes, and snippets.

@Ocramius /User.php
Last active May 23, 2016

Doctrine 2 ManyToMany - the correct way
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table(name="user")
*/
class User
{
/**
* @var int|null
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer", name="id")
*/
protected $id;
/**
* @var \Doctrine\Common\Collections\Collection|UserGroup[]
*
* @ORM\ManyToMany(targetEntity="UserGroup", inversedBy="users")
* @ORM\JoinTable(
* name="user_usergroup",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="usergroup_id", referencedColumnName="id")
* }
* )
*/
protected $userGroups;
/**
* Default constructor, initializes collections
*/
public function __construct()
{
$this->userGroups = new ArrayCollection();
}
/**
* @param UserGroup $userGroup
*/
public function addUserGroup(UserGroup $userGroup)
{
if ($this->userGroups->contains($userGroup)) {
return;
}
$this->userGroups->add($userGroup);
$userGroup->addUser($this);
}
/**
* @param UserGroup $userGroup
*/
public function removeUserGroup(UserGroup $userGroup)
{
if (!$this->userGroups->contains($userGroup)) {
return;
}
$this->userGroups->removeElement($userGroup);
$userGroup->removeUser($this);
}
}
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity()
* @ORM\Table(name="usergroup")
*/
class UserGroup
{
/**
* @var int|null
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer", name="id")
*/
protected $id;
/**
* @var \Doctrine\Common\Collections\Collection|User[]
*
* @ORM\ManyToMany(targetEntity="User", mappedBy="userGroups")
*/
protected $users;
/**
* Default constructor, initializes collections
*/
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* @param User $user
*/
public function addUser(User $user)
{
if ($this->users->contains($user)) {
return;
}
$this->users->add($user);
$user->addUserGroup($this);
}
/**
* @param User $user
*/
public function removeUser(User $user)
{
if (!$this->users->contains($user)) {
return;
}
$this->users->removeElement($user);
$user->removeUserGroup($this);
}
}
@basz
basz commented Dec 3, 2012

mappedBy="blocks"??? shouldn't that be mappedBy="groups"

@basz
basz commented Dec 3, 2012

idem for inversedBy="blocks"?

@Ocramius
Owner

@basz fixed

@JulienDotDev

In User.php :

"protected $groups ;"

but you are using the var $userGroups everywher :

"$this->userGroups = new ArrayCollection();"
...

@Ocramius
Owner
@sliman1345

@Ocramius
No, this not Fixed, this is infinite loop !!

 "addUser"  => "addUserGroup" => "addUser" => "addUserGroup" => "addUser" => ...

Just remove "$user->addUserGroup($this);" from the Entity "UserGroup", its fine.
And keep "$userGroup->addUser($this);" in "User" Entity (synchronously updating inverse side).

@Ocramius
Owner
Ocramius commented Jan 2, 2015

@sliman1345 I don't see an infinite loop here: the loop is terminated because of early returns in case no operation has to be applied

@fyrye
fyrye commented Jan 28, 2015

UserGroups.php

@ORM\ManyToMany(targetEntity="User", mappedBy="groups")

There is no property named $groups, shouldn't it be

@ORM\ManyToMany(targetEntity="User", mappedBy="userGroups")
@Ocramius
Owner

@fyrye thanks, updated!

@Nijusan
Nijusan commented May 12, 2016

so i implemented products and categories with many to many the same way as described, but something i am missing...
when i want all categories of a product ($product-getCategories()) i only get a persistant-collection that is not initialized. so to really get an array of all categories i need to initialize it... ? isnt there a way that this happens automatically as it is with other relations?

on stackoverflow i read something about fetch=EAGER, but then the query for collecting the categories is always fired, even when i am not calling ->getCategories()

@rogerwalt

You could always use the orm:generate-entities command, see here. If your associations are correct, this will produce the correct constructors and getter/setter methods for your entities. Also, the orm:validate-schema command will tell you what is wrong with your entity relations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.