【问题标题】:Doctrine: How to unset (SET NULL) OneToMany relationship教义:如何取消设置(SET NULL)OneToMany 关系
【发布时间】:2014-06-10 15:44:57
【问题描述】:

这是一个非常非常简单的行为,但是我找不到用教义实现它的方法。我将解释它仅使用两个实体来降低复杂性。

有两个相关的实体(作者和书籍),例如“一个作者拥有零个或多个书籍”和“一本书由零个或一个作者拥有”,我正在尝试取消作者与他的一个作者之间的关系书籍(来自作者方面),期望数据库中的 book.author_id 字段设置为空。

实体定义如下:

作者

/**
 * Author
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\AuthorRepository")
 */
class Author
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


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

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

        return $this;
    }

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

    /**
     * @ORM\OneToMany(targetEntity="Book", mappedBy="author", cascade={"persist", "remove"})
     */
    private $books;

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

    /**
     * Add books
     *
     * @param \Poc\PocBundle\Entity\Book $books
     * @return Author
     */
    public function addBook(\Poc\PocBundle\Entity\Book $books)
    {
        $this->books[] = $books;

        return $this;
    }

    /**
     * Remove books
     *
     * @param \Poc\PocBundle\Entity\Book $books
     */
    public function removeBook(\Poc\PocBundle\Entity\Book $books)
    {
        $this->books->removeElement($books);
    }

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

图书

/**
 * Book
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\BookRepository")
 */
class Book
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


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

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

        return $this;
    }

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

    /**
     * @ORM\ManyToOne(targetEntity="Author", inversedBy="books")
     * @ORM\JoinColumn(name="author_id", referencedColumnName="id", onDelete="SET NULL")
     */
     protected $author;


    /**
     * Set author
     *
     * @param \Poc\PocBundle\Entity\Author $author
     * @return Book
     */
    public function setAuthor(\Poc\PocBundle\Entity\Author $author = null)
    {
        $this->author = $author;

        return $this;
    }

    /**
     * Get author
     *
     * @return \Poc\PocBundle\Entity\Author 
     */
    public function getAuthor()
    {
        return $this->author;
    }
}

在主控制器中,我执行以下操作。

  • 检索作者

  • 检索此作者拥有的图书

  • 从作者手中删除图书

  • 坚持作者和刷新

  • 检索书

  • 获取作者...

作者保持不变。在数据库中,该记录的字段 book.author_id 没有按预期设置为 NULL,但仍与作者相关。

控制器代码:

    $Book = $this->getDoctrine()
        ->getRepository('PocPocBundle:Book')
        ->find('1');
    $Author = $this->getDoctrine()
        ->getRepository('PocPocBundle:Author')
        ->find('1');

    $Author->removeBook($Book);


    $em = $this->getDoctrine()->getManager();
    $em->persist($Author);
    $em->flush();

    echo "<pre>";
    $Book = $this->getDoctrine()
        ->getRepository('PocPocBundle:Book')
        ->find('1');
    \Doctrine\Common\Util\Debug::dump($Book);

    die;

...以及输出

object(stdClass)[286]
      public '__CLASS__' => string 'Poc\PocBundle\Entity\Book' (length=25)
      public 'id' => int 1
      public 'name' => string 'El Quijote' (length=10)
      public 'author' => 
        object(stdClass)[293]
          public '__CLASS__' => string 'Poc\PocBundle\Entity\Author' (length=27)
          public '__IS_PROXY__' => boolean true
          public '__PROXY_INITIALIZED__' => boolean true
          public 'id' => int 1
          public 'name' => string 'Cervantes' (length=9)
          public 'books' => string 'Array(1)' (length=8)

在实体 Book (id=1) 的输出中,我们可以看到这本书仍然与作者相关。

当然,我遗漏了一些东西,但我找不到差距在哪里。

【问题讨论】:

  • 既然要删除,为什么还要坚持?最好在顶部定义$em = $this-&gt;getDoctrine()-&gt;getManager();,然后基于$em 应用所有更改,最后你只是$em-&gt;flush(); 我认为单独选择书和作者然后删除不是一个好主意;你如何确保id为1的作者与id为1的书相关?!
  • 在这个例子中,为了澄清行为,我将书和作者分开。真正的应用程序不会这样做,但我已将问题简化为此示例以简化它。
  • 那如果要删除为什么还要坚持呢?此外,在您编辑后,您需要通过 $em-&gt;refresh($Book); 刷新实体,然后您可以打印所有新的更新值

标签: php symfony doctrine-orm one-to-many


【解决方案1】:

如果您想删除 Author 和 Book 实体之间的关联,您应该删除 Book 实体中的关联,并使用 $em->flush() 将其保留。 $em->persist($entity) 不用于实体删除。删除 PHP 对象中的关联并通过 ORM 刷新它们删除数据库中的关联。

只需在 Doctrine 的文档中查看:

http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#removing-associations

我希望它对你有用。干杯!

【讨论】:

  • 那是!!! ... 在 removeBook、$Book-&gt;setAuthor(null); 之后,一切都完成了!非常感谢!!!
猜你喜欢
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多