Doctrine - ManyToMany与删除的关系

时间:2015-10-29 13:28:24

标签: php doctrine-orm

我需要在两个实体之间创建ManyToMany关系。接下来我试图删除一些行,但它不起作用。没有错误发生,没有数据库删除 - 没有 - 好像从未启动过。你能帮我解决这个问题吗?

平铺实体

<?php

namespace AppBundle\Entity;

use AppBundle\Traits\Timestampable;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * ORM\Entity(repositoryClass="AppBundle\Entity\Repository\TileRepository")
 * @ORM\Table(name="tile")
 *
 */
class Tile
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

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

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

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

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

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\User", inversedBy="tiles", cascade={"remove", "persist"})
     * @ORM\JoinTable(name="users_tiles")
     **/
    protected $user;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->user = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set type
     *
     * @param string $type
     *
     * @return Tile
     */
    public function setType($type)
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Get type
     *
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Tile
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set start
     *
     * @param string $start
     *
     * @return Tile
     */
    public function setStart($start)
    {
        $this->start = $start;

        return $this;
    }

    /**
     * Get start
     *
     * @return string
     */
    public function getStart()
    {
        return $this->start;
    }

    /**
     * Set end
     *
     * @param string $end
     *
     * @return Tile
     */
    public function setEnd($end)
    {
        $this->end = $end;

        return $this;
    }

    /**
     * Get end
     *
     * @return string
     */
    public function getEnd()
    {
        return $this->end;
    }

    /**
     * Add user
     *
     * @param \AppBundle\Entity\User $user
     *
     * @return Tile
     */
    public function addUser(\AppBundle\Entity\User $user)
    {
        $this->user[] = $user;

        return $this;
    }

    /**
     * Remove user
     *
     * @param \AppBundle\Entity\User $user
     */
    public function removeUser(\AppBundle\Entity\User $user)
    {
        $this->user->removeElement($user);
    }

    /**
     * Get user
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUser()
    {
        return $this->user;
    }
}

用户实体

<?php
// src/AppBundle/Entity/User.php

namespace AppBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
     * @ORM\JoinTable(name="fos_user_user_group",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;


    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Tile", mappedBy="user")
     */
    protected $tiles;


    /**
     * Add tile
     *
     * @param \AppBundle\Entity\Tile $tile
     *
     * @return User
     */
    public function addTile(\AppBundle\Entity\Tile $tile)
    {
        $this->tiles[] = $tile;

        return $this;
    }

    /**
     * Remove tile
     *
     * @param \AppBundle\Entity\Tile $tile
     */
    public function removeTile(\AppBundle\Entity\Tile $tile)
    {
        $tile->setUser(null);
        $this->tiles->removeElement($tile);
    }

    /**
     * Get tiles
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getTiles()
    {
        return $this->tiles;
    }
}

和控制器类的一部分

 $user = $this->getUser();

    foreach($user->getTiles() as $tile) {
        echo $tile->getName();
        $user->removeTile($tile);
    }
    $em->persist($user);
    $em->flush();

此外,我还尝试使用以下内容添加新记录:

foreach($data as $tile) {
    $user->addTile($em->getReference('AppBundle:Tile', $tile));
}
$em->persist($user);
$em->flush();

但这也没有奏效。没有发生错误,没有数据库插入。

2 个答案:

答案 0 :(得分:0)

您的用户似乎是反面而您的Tiles是拥有方。因此,反面的更新不会反映您的更新。尝试切换拥有方或更新时更新磁贴。

请参阅doctrine docs

  

反面必须使用OneToOne的mappedBy属性,   OneToMany或ManyToMany映射声明。 mappedBy属性   包含所属方的关联字段的名称。该   拥有方必须使用OneToOne的inversedBy属性,   ManyToOne,或ManyToMany映射声明。 inversedBy属性   包含反面的关联字段的名称。

  

Doctrine只会检查协会的拥有方是否有变更。

     

要完全理解这一点,请记住双向关联的方式   维持在对象世界。每侧有2个参考   关联和这两个引用都代表相同   关联但可以彼此独立地改变。当然,在   一个正确的应用程序双向关联的语义   应用程序开发人员正确维护(这是他的   责任)。学说需要知道这两个中的哪一个在记忆中   引用是应该持久化的,而不是。这是   拥有/反向概念主要用于什么。

     

忽略仅对关联的反面进行的更改。   确保更新双向关联的两侧(或在   至少是拥有方,从学说的角度来看)

     

双向关联的拥有方是边缘主义   在确定关联状态时“看着”,并且   因此,更新关联是否有任何事情要做   在数据库中。

     

“拥有方”和“反方”是ORM的技术概念   技术,而不是您的域模型的概念。你认为是什么   您的域模型中的拥有方可以与   拥有一方是为了学说。这些是无关的。

答案 1 :(得分:0)

作为@k0pernikus said,只能从一侧进行。因此,如果您想在两侧使用它,则需要修改反向实体。

改变自:

/**
 * Add tile
 *
 * @param \AppBundle\Entity\Tile $tile
 *
 * @return User
 */
public function addTile(\AppBundle\Entity\Tile $tile)
{
    $this->tiles[] = $tile;

    return $this;
}

/**
 * Remove tile
 *
 * @param \AppBundle\Entity\Tile $tile
 */
public function removeTile(\AppBundle\Entity\Tile $tile)
{
    $this->tiles->removeElement($tile);
}

    /**
     * Add tile
     *
     * @param \AppBundle\Entity\Tile $tile
     *
     * @return User
     */
    public function addTile(\AppBundle\Entity\Tile $tile)
    {
        $tile->addUser($this);

        return $this;
    }

    /**
     * Remove tile
     *
     * @param \AppBundle\Entity\Tile $tile
     */
    public function removeTile(\AppBundle\Entity\Tile $tile)
    {
        $this->tiles->removeElement($tile);
        $tile->removeUser($this);
    }