问题
In my Symfony2 project I have two related entities: Users and Favorites. They have a many-to-many relationship.
My application works as follows: In my Twig-page I have an few items with a button 'Add to Favorites'. When you click the button my controller saves the item_id in the Favorites column. But then I want to save the user who added the item to his favorites and here my application fails.
The User and the favorite exist but the joincolumn between Users and Favorites remains empty. I also don't receive any kind of errors.
Here is my code:
Entity Users
class Users implements AdvancedUserInterface
{
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
* @ORM\JoinTable(name="user_has_favorite",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")
* }
* )
*/
private $favorite;
public function __construct()
{
$this->favorite = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addFavorite(\Geo\CityTroopersBundle\Entity\Favorites $favorite)
{
$this->favorite[] = $favorite;
return $this;
}
...
Entity Favorites
class Favorites
{
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Users", mappedBy="favorite", cascade={"persist"})
*/
private $user;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addUser(\Geo\CityTroopersBundle\Entity\Users $user)
{
$this->user[] = $user;
return $this;
}
My controller
public function showNewsAction()
{
$request = $this->get('request');
$itemId=$request->request->get('itemId');
if($itemId != NULL)
{
//MAKE NEW FAVORITE AND ADD TO DATABASE LINKED WITH ITEM
$favorite = new Favorites();
$favorite->setItemId($itemId);
//LINK FAVORITE ID WITH USER ID IN JOINCOLUMN
$userId = 6;
$em = $this->getDoctrine()->getEntityManager();
$user = $em->getRepository('GeoCityTroopersBundle:Users')->find($userId);
$favorite->addUser($user);
$em->persist($favorite);
//I TRIED THIS TOO, BUT IT FAILED
/*$user->addFavorite($favorite);
$em->persist($user);*/
$em->flush();
回答1:
You were close there. For doctrine many-to-many relationships, you need to call both add methods
$favorite->addUser($user);
$user->addFavorite($favorite);
$em->persist($favorite);
$em->persist($user);
$em->flush();
This should do the trick. In the docs they do this, but don't mention it too explicitly. Not sure why either because lots of people run into this (myself included).
回答2:
As explained here, only the owning side is responsible for the connection management : http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#owning-and-inverse-side-on-a-manytomany-association
So only
$user->addFavorite($favorite);
should persist, and not
$favorite->addUser($user);
回答3:
Like indicated by Cedric, adding a record for a many to many relation is done only in one direction and it depends on how you defined the relation: adding can be done only by the parent entity of the relation, so in your case you must use:
$user->addFavorite($favorite);
回答4:
In your line :
@ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")
The
name="favorite_id"
part refers to the columns in the join table, whereas the
referencedColumnName="favorite_id"
refers to the id in the favorite table which usualy is simply "id". You should try :
/**
* @var \Doctrine\Common\Collections\ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
* @ORM\JoinTable(name="user_has_favorite",
* joinColumns={
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="favorite_id", referencedColumnName="id")
* }
* )
*/
private $favorite;
来源:https://stackoverflow.com/questions/14159307/saving-many-to-many-relationship-to-database-in-symfony2