繁体   English   中英

原则-与删除的ManyToMany关系

[英]Doctrine - ManyToMany relationship with deleting

我需要在两个实体之间创建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();

但这也行不通。 没有发生错误,没有数据库插入。

您的用户似乎是相反的一面,而图块则是其拥有的一面。 因此,反面的更新不会反映您的更新。 尝试切换拥有方或在更新时更新磁贴。

参见学说文档

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

原则将仅检查关联的拥有方以进行更改。

要完全理解这一点,请记住在对象世界中如何维护双向关联。 关联的每一侧都有2个引用,这2个引用都表示相同的关联,但可以彼此独立地进行更改。 当然,在正确的应用程序中,双向关联的语义由应用程序开发人员正确维护(这是他的责任)。 教义需要知道这两个内存引用中的哪一个是应该持久的,哪些不是。 这就是拥有/反向概念的主要用途。

仅对关联的反面所做的更改将被忽略。 确保更新双向关联的双方(或者从Doctrine的角度来看至少更新拥有方)

双向关联的拥有方是Doctrine在确定关联的状态时“关注”的一面,因此,在数据库中是否有任何事情可以更新关联。

“拥有方”和“相反方”是ORM技术的技术概念,而不是域模型的概念。 在域模型中,您认为拥有权的一方可能不同于Doctrine拥有权的一方。 这些无关。

正如@ k0pernikus所说 ,仅从一侧是可能的。 因此,如果您想同时使用它,则需要修改逆实体。

所以从:

/**
 * 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);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM